fix(sync): tune hdmi av alignment
This commit is contained in:
parent
5d6d07d375
commit
8236b43b54
6
Cargo.lock
generated
6
Cargo.lock
generated
@ -1642,7 +1642,7 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lesavka_client"
|
name = "lesavka_client"
|
||||||
version = "0.13.1"
|
version = "0.13.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-stream",
|
"async-stream",
|
||||||
@ -1676,7 +1676,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lesavka_common"
|
name = "lesavka_common"
|
||||||
version = "0.13.1"
|
version = "0.13.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
@ -1688,7 +1688,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lesavka_server"
|
name = "lesavka_server"
|
||||||
version = "0.13.1"
|
version = "0.13.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
|
|||||||
@ -4,7 +4,7 @@ path = "src/main.rs"
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "lesavka_client"
|
name = "lesavka_client"
|
||||||
version = "0.13.1"
|
version = "0.13.2"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "lesavka_common"
|
name = "lesavka_common"
|
||||||
version = "0.13.1"
|
version = "0.13.2"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
|
||||||
|
|||||||
@ -98,6 +98,7 @@ Hardware-facing assumptions belong near the code that uses them; this file is th
|
|||||||
| `LESAVKA_HDMI_CONNECTOR` | server hardware/device override |
|
| `LESAVKA_HDMI_CONNECTOR` | server hardware/device override |
|
||||||
| `LESAVKA_HDMI_DRIVER` | server hardware/device override |
|
| `LESAVKA_HDMI_DRIVER` | server hardware/device override |
|
||||||
| `LESAVKA_HDMI_FBDEV` | server hardware/device override |
|
| `LESAVKA_HDMI_FBDEV` | server hardware/device override |
|
||||||
|
| `LESAVKA_HDMI_PRESENTATION_DELAY_US` | server HDMI video latency override |
|
||||||
| `LESAVKA_HDMI_HEIGHT` | server hardware/device override |
|
| `LESAVKA_HDMI_HEIGHT` | server hardware/device override |
|
||||||
| `LESAVKA_HDMI_MODES` | server hardware/device override |
|
| `LESAVKA_HDMI_MODES` | server hardware/device override |
|
||||||
| `LESAVKA_HDMI_RESTORE_CRTC` | server hardware/device override |
|
| `LESAVKA_HDMI_RESTORE_CRTC` | server hardware/device override |
|
||||||
@ -184,7 +185,7 @@ Hardware-facing assumptions belong near the code that uses them; this file is th
|
|||||||
| `LESAVKA_UAC_BUFFER_TIME_US` | server audio sink latency override |
|
| `LESAVKA_UAC_BUFFER_TIME_US` | server audio sink latency override |
|
||||||
| `LESAVKA_UAC_COMPENSATION_US` | server audio sink latency override |
|
| `LESAVKA_UAC_COMPENSATION_US` | server audio sink latency override |
|
||||||
| `LESAVKA_UAC_DEV` | server hardware/device override |
|
| `LESAVKA_UAC_DEV` | server hardware/device override |
|
||||||
| `LESAVKA_UAC_HDMI_COMPENSATION_US` | server audio sink latency override |
|
| `LESAVKA_UAC_HDMI_COMPENSATION_US` | server HDMI audio sink latency override |
|
||||||
| `LESAVKA_UAC_LATENCY_TIME_US` | server audio sink latency override |
|
| `LESAVKA_UAC_LATENCY_TIME_US` | server audio sink latency override |
|
||||||
| `LESAVKA_TEST_CAM_U32` | test/build contract variable; not runtime operator config |
|
| `LESAVKA_TEST_CAM_U32` | test/build contract variable; not runtime operator config |
|
||||||
| `LESAVKA_TEST_CAP_CAMERA` | test/build contract variable; not runtime operator config |
|
| `LESAVKA_TEST_CAP_CAMERA` | test/build contract variable; not runtime operator config |
|
||||||
|
|||||||
@ -278,7 +278,7 @@
|
|||||||
},
|
},
|
||||||
"server/src/audio/voice_input.rs": {
|
"server/src/audio/voice_input.rs": {
|
||||||
"line_percent": 100.0,
|
"line_percent": 100.0,
|
||||||
"loc": 358
|
"loc": 360
|
||||||
},
|
},
|
||||||
"server/src/bin/lesavka_uvc/control_payloads.rs": {
|
"server/src/bin/lesavka_uvc/control_payloads.rs": {
|
||||||
"line_percent": 100.0,
|
"line_percent": 100.0,
|
||||||
@ -410,7 +410,7 @@
|
|||||||
},
|
},
|
||||||
"server/src/video_sinks/hdmi_sink.rs": {
|
"server/src/video_sinks/hdmi_sink.rs": {
|
||||||
"line_percent": 100.0,
|
"line_percent": 100.0,
|
||||||
"loc": 393
|
"loc": 423
|
||||||
},
|
},
|
||||||
"server/src/video_sinks/webcam_sink.rs": {
|
"server/src/video_sinks/webcam_sink.rs": {
|
||||||
"line_percent": 100.0,
|
"line_percent": 100.0,
|
||||||
|
|||||||
@ -433,8 +433,10 @@ fi
|
|||||||
printf 'LESAVKA_HDMI_SINK=%s\n' "${LESAVKA_HDMI_SINK:-fbdevsink}"
|
printf 'LESAVKA_HDMI_SINK=%s\n' "${LESAVKA_HDMI_SINK:-fbdevsink}"
|
||||||
printf 'LESAVKA_HDMI_FBDEV=%s\n' "${LESAVKA_HDMI_FBDEV:-/dev/fb0}"
|
printf 'LESAVKA_HDMI_FBDEV=%s\n' "${LESAVKA_HDMI_FBDEV:-/dev/fb0}"
|
||||||
printf 'LESAVKA_HDMI_DRIVER=%s\n' "${LESAVKA_HDMI_DRIVER:-vc4}"
|
printf 'LESAVKA_HDMI_DRIVER=%s\n' "${LESAVKA_HDMI_DRIVER:-vc4}"
|
||||||
|
printf 'LESAVKA_HDMI_PRESENTATION_DELAY_US=%s\n' "${LESAVKA_HDMI_PRESENTATION_DELAY_US:-180000}"
|
||||||
printf 'LESAVKA_UAC_DEV=%s\n' "${LESAVKA_UAC_DEV:-hw:UAC2Gadget,0}"
|
printf 'LESAVKA_UAC_DEV=%s\n' "${LESAVKA_UAC_DEV:-hw:UAC2Gadget,0}"
|
||||||
printf 'LESAVKA_ALSA_DEV=%s\n' "${LESAVKA_ALSA_DEV:-hw:UAC2Gadget,0}"
|
printf 'LESAVKA_ALSA_DEV=%s\n' "${LESAVKA_ALSA_DEV:-hw:UAC2Gadget,0}"
|
||||||
|
printf 'LESAVKA_UAC_HDMI_COMPENSATION_US=%s\n' "${LESAVKA_UAC_HDMI_COMPENSATION_US:-0}"
|
||||||
} | sudo tee /etc/lesavka/server.env >/dev/null
|
} | sudo tee /etc/lesavka/server.env >/dev/null
|
||||||
|
|
||||||
echo "==> 6a. Systemd units - lesavka-core"
|
echo "==> 6a. Systemd units - lesavka-core"
|
||||||
|
|||||||
@ -21,6 +21,7 @@ LOCAL_OUTPUT_DIR=${LOCAL_OUTPUT_DIR:-"${REPO_ROOT}/tmp"}
|
|||||||
VIDEO_SIZE=${VIDEO_SIZE:-1280x720}
|
VIDEO_SIZE=${VIDEO_SIZE:-1280x720}
|
||||||
VIDEO_FPS=${VIDEO_FPS:-30}
|
VIDEO_FPS=${VIDEO_FPS:-30}
|
||||||
VIDEO_FORMAT=${VIDEO_FORMAT:-mjpeg}
|
VIDEO_FORMAT=${VIDEO_FORMAT:-mjpeg}
|
||||||
|
REMOTE_AUDIO_SOURCE=${REMOTE_AUDIO_SOURCE:-auto}
|
||||||
SSH_OPTS=${SSH_OPTS:-"-o BatchMode=yes -o ConnectTimeout=5"}
|
SSH_OPTS=${SSH_OPTS:-"-o BatchMode=yes -o ConnectTimeout=5"}
|
||||||
|
|
||||||
mkdir -p "${LOCAL_OUTPUT_DIR}"
|
mkdir -p "${LOCAL_OUTPUT_DIR}"
|
||||||
@ -33,13 +34,15 @@ ssh ${SSH_OPTS} "${TETHYS_HOST}" bash -s -- \
|
|||||||
"${CAPTURE_SECONDS}" \
|
"${CAPTURE_SECONDS}" \
|
||||||
"${VIDEO_SIZE}" \
|
"${VIDEO_SIZE}" \
|
||||||
"${VIDEO_FPS}" \
|
"${VIDEO_FPS}" \
|
||||||
"${VIDEO_FORMAT}" <<'REMOTE_CAPTURE_SCRIPT' &
|
"${VIDEO_FORMAT}" \
|
||||||
|
"${REMOTE_AUDIO_SOURCE}" <<'REMOTE_CAPTURE_SCRIPT' &
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
remote_capture=$1
|
remote_capture=$1
|
||||||
capture_seconds=$2
|
capture_seconds=$2
|
||||||
video_size=$3
|
video_size=$3
|
||||||
video_fps=$4
|
video_fps=$4
|
||||||
video_format=$5
|
video_format=$5
|
||||||
|
remote_audio_source=$6
|
||||||
|
|
||||||
rm -f "${remote_capture}"
|
rm -f "${remote_capture}"
|
||||||
video_args=(-f video4linux2 -framerate "${video_fps}" -video_size "${video_size}")
|
video_args=(-f video4linux2 -framerate "${video_fps}" -video_size "${video_size}")
|
||||||
@ -47,17 +50,73 @@ if [[ -n "${video_format}" ]]; then
|
|||||||
video_args+=(-input_format "${video_format}")
|
video_args+=(-input_format "${video_format}")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ffmpeg -hide_banner -loglevel error -y \
|
resolve_pulse_source() {
|
||||||
-thread_queue_size 1024 \
|
if ! command -v pactl >/dev/null 2>&1; then
|
||||||
"${video_args[@]}" \
|
return 1
|
||||||
-i /dev/video0 \
|
fi
|
||||||
-thread_queue_size 1024 \
|
pactl list short sources 2>/dev/null \
|
||||||
-f alsa -ac 2 -ar 48000 \
|
| awk '
|
||||||
-i hw:3,0 \
|
/alsa_input\..*Lesavka_Composite/ { print $2; found=1; exit }
|
||||||
-t "${capture_seconds}" \
|
/Lesavka_Composite/ && !fallback { fallback=$2 }
|
||||||
-c:v ffv1 -level 3 -g 1 \
|
END {
|
||||||
-c:a pcm_s16le \
|
if (found) exit 0
|
||||||
"${remote_capture}"
|
if (fallback != "") { print fallback; exit 0 }
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
'
|
||||||
|
}
|
||||||
|
|
||||||
|
audio_mode="alsa"
|
||||||
|
alsa_audio_dev="hw:3,0"
|
||||||
|
pulse_source=""
|
||||||
|
if [[ "${remote_audio_source}" == "auto" ]]; then
|
||||||
|
if pulse_source="$(resolve_pulse_source)"; then
|
||||||
|
audio_mode="pipewire"
|
||||||
|
else
|
||||||
|
printf 'PipeWire Lesavka source not found; falling back to hw:3,0\n' >&2
|
||||||
|
fi
|
||||||
|
elif [[ "${remote_audio_source}" == pulse:* ]]; then
|
||||||
|
audio_mode="pipewire"
|
||||||
|
pulse_source="${remote_audio_source#pulse:}"
|
||||||
|
elif [[ "${remote_audio_source}" == alsa:* ]]; then
|
||||||
|
alsa_audio_dev="${remote_audio_source#alsa:}"
|
||||||
|
else
|
||||||
|
printf 'unsupported REMOTE_AUDIO_SOURCE=%s\n' "${remote_audio_source}" >&2
|
||||||
|
exit 64
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${audio_mode}" == "pipewire" ]]; then
|
||||||
|
printf 'using PipeWire source: %s\n' "${pulse_source}" >&2
|
||||||
|
pw-record --target "${pulse_source}" \
|
||||||
|
--rate 48000 \
|
||||||
|
--channels 2 \
|
||||||
|
--format s16 \
|
||||||
|
--latency 10ms \
|
||||||
|
--raw - | \
|
||||||
|
ffmpeg -hide_banner -loglevel error -y \
|
||||||
|
-thread_queue_size 1024 \
|
||||||
|
"${video_args[@]}" \
|
||||||
|
-i /dev/video0 \
|
||||||
|
-thread_queue_size 1024 \
|
||||||
|
-f s16le -ac 2 -ar 48000 \
|
||||||
|
-i pipe:0 \
|
||||||
|
-t "${capture_seconds}" \
|
||||||
|
-c:v ffv1 -level 3 -g 1 \
|
||||||
|
-c:a pcm_s16le \
|
||||||
|
"${remote_capture}"
|
||||||
|
else
|
||||||
|
ffmpeg -hide_banner -loglevel error -y \
|
||||||
|
-thread_queue_size 1024 \
|
||||||
|
"${video_args[@]}" \
|
||||||
|
-i /dev/video0 \
|
||||||
|
-thread_queue_size 1024 \
|
||||||
|
-f alsa -ac 2 -ar 48000 \
|
||||||
|
-i "${alsa_audio_dev}" \
|
||||||
|
-t "${capture_seconds}" \
|
||||||
|
-c:v ffv1 -level 3 -g 1 \
|
||||||
|
-c:a pcm_s16le \
|
||||||
|
"${remote_capture}"
|
||||||
|
fi
|
||||||
REMOTE_CAPTURE_SCRIPT
|
REMOTE_CAPTURE_SCRIPT
|
||||||
capture_pid=$!
|
capture_pid=$!
|
||||||
|
|
||||||
@ -87,9 +146,13 @@ if [[ "${probe_status}" -ne 0 ]]; then
|
|||||||
exit "${probe_status}"
|
exit "${probe_status}"
|
||||||
fi
|
fi
|
||||||
if [[ "${capture_status}" -ne 0 ]]; then
|
if [[ "${capture_status}" -ne 0 ]]; then
|
||||||
|
if [[ "${capture_status}" -eq 141 && -f "${LOCAL_CAPTURE}" ]]; then
|
||||||
|
echo "Tethys capture ended with PipeWire SIGPIPE after ffmpeg closed; accepting preserved capture ${LOCAL_CAPTURE}" >&2
|
||||||
|
else
|
||||||
echo "Tethys capture failed with status ${capture_status}" >&2
|
echo "Tethys capture failed with status ${capture_status}" >&2
|
||||||
[[ -f "${LOCAL_CAPTURE}" ]] && echo "partial capture preserved at ${LOCAL_CAPTURE}" >&2
|
[[ -f "${LOCAL_CAPTURE}" ]] && echo "partial capture preserved at ${LOCAL_CAPTURE}" >&2
|
||||||
exit "${capture_status}"
|
exit "${capture_status}"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "==> analyzing capture"
|
echo "==> analyzing capture"
|
||||||
|
|||||||
@ -10,7 +10,7 @@ bench = false
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "lesavka_server"
|
name = "lesavka_server"
|
||||||
version = "0.13.1"
|
version = "0.13.2"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
autobins = false
|
autobins = false
|
||||||
|
|
||||||
|
|||||||
@ -81,7 +81,9 @@ fn voice_sink_compensation_us() -> i64 {
|
|||||||
fn default_voice_sink_compensation_us() -> i64 {
|
fn default_voice_sink_compensation_us() -> i64 {
|
||||||
let cfg = crate::camera::current_camera_config();
|
let cfg = crate::camera::current_camera_config();
|
||||||
if cfg.output == crate::camera::CameraOutput::Hdmi {
|
if cfg.output == crate::camera::CameraOutput::Hdmi {
|
||||||
non_negative_voice_sink_timing_env("LESAVKA_UAC_HDMI_COMPENSATION_US", 105_000)
|
// HDMI now prefers MJPEG on hosts without hardware H.264 decode, which
|
||||||
|
// removed the old video-side lag that justified the large audio pad.
|
||||||
|
non_negative_voice_sink_timing_env("LESAVKA_UAC_HDMI_COMPENSATION_US", 0)
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
@ -336,8 +338,8 @@ mod voice_sink_timing_tests {
|
|||||||
temp_env::with_var_unset("LESAVKA_UAC_HDMI_COMPENSATION_US", || {
|
temp_env::with_var_unset("LESAVKA_UAC_HDMI_COMPENSATION_US", || {
|
||||||
temp_env::with_var("LESAVKA_CAM_OUTPUT", Some("hdmi"), || {
|
temp_env::with_var("LESAVKA_CAM_OUTPUT", Some("hdmi"), || {
|
||||||
update_camera_config();
|
update_camera_config();
|
||||||
assert_eq!(default_voice_sink_compensation_us(), 105_000);
|
assert_eq!(default_voice_sink_compensation_us(), 0);
|
||||||
assert_eq!(voice_sink_compensation_us(), 105_000);
|
assert_eq!(voice_sink_compensation_us(), 0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -107,10 +107,7 @@ fn preferred_uac_candidates_include_detected_cards_before_alias_fallbacks() {
|
|||||||
],
|
],
|
||||||
|| {
|
|| {
|
||||||
let candidates = preferred_uac_device_candidates("hw:UAC2Gadget,0");
|
let candidates = preferred_uac_device_candidates("hw:UAC2Gadget,0");
|
||||||
assert_eq!(
|
assert_eq!(candidates.first().map(String::as_str), Some("hw:7,3"));
|
||||||
candidates.first().map(String::as_str),
|
|
||||||
Some("hw:7,3")
|
|
||||||
);
|
|
||||||
assert!(candidates.iter().any(|value| value == "plughw:7,3"));
|
assert!(candidates.iter().any(|value| value == "plughw:7,3"));
|
||||||
assert!(
|
assert!(
|
||||||
candidates
|
candidates
|
||||||
|
|||||||
@ -10,6 +10,7 @@ pub struct HdmiSink {
|
|||||||
pipe: gst::Pipeline,
|
pipe: gst::Pipeline,
|
||||||
next_pts_us: AtomicU64,
|
next_pts_us: AtomicU64,
|
||||||
frame_step_us: u64,
|
frame_step_us: u64,
|
||||||
|
presentation_delay_us: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(not(coverage), test))]
|
#[cfg(any(not(coverage), test))]
|
||||||
@ -17,6 +18,15 @@ fn hdmi_queue_buffers() -> u32 {
|
|||||||
crate::video_support::env_u32("LESAVKA_HDMI_QUEUE_BUFFERS", 1).max(1)
|
crate::video_support::env_u32("LESAVKA_HDMI_QUEUE_BUFFERS", 1).max(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(not(coverage), test))]
|
||||||
|
fn hdmi_presentation_delay_us() -> u64 {
|
||||||
|
// The HDMI + capture-adapter path still lands video earlier than the UAC
|
||||||
|
// path on Tethys-style consumers, even after the stale audio holdback was
|
||||||
|
// removed. Start with a measured default that keeps A/V within one video
|
||||||
|
// frame instead of requiring per-host hand tuning.
|
||||||
|
crate::video_support::env_u32("LESAVKA_HDMI_PRESENTATION_DELAY_US", 180_000) as u64
|
||||||
|
}
|
||||||
|
|
||||||
impl HdmiSink {
|
impl HdmiSink {
|
||||||
/// Build a new HDMI sink pipeline.
|
/// Build a new HDMI sink pipeline.
|
||||||
///
|
///
|
||||||
@ -49,6 +59,7 @@ impl HdmiSink {
|
|||||||
pipe: pipeline,
|
pipe: pipeline,
|
||||||
next_pts_us: AtomicU64::new(0),
|
next_pts_us: AtomicU64::new(0),
|
||||||
frame_step_us,
|
frame_step_us,
|
||||||
|
presentation_delay_us: 0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,6 +93,7 @@ impl HdmiSink {
|
|||||||
.build()?;
|
.build()?;
|
||||||
|
|
||||||
let queue_depth = hdmi_queue_buffers();
|
let queue_depth = hdmi_queue_buffers();
|
||||||
|
let presentation_delay_us = hdmi_presentation_delay_us();
|
||||||
let queue = gst::ElementFactory::make("queue")
|
let queue = gst::ElementFactory::make("queue")
|
||||||
.property("max-size-buffers", queue_depth)
|
.property("max-size-buffers", queue_depth)
|
||||||
.property("max-size-bytes", 0u32)
|
.property("max-size-bytes", 0u32)
|
||||||
@ -94,6 +106,7 @@ impl HdmiSink {
|
|||||||
tracing::info!(
|
tracing::info!(
|
||||||
target: "lesavka_server::video",
|
target: "lesavka_server::video",
|
||||||
queue_depth,
|
queue_depth,
|
||||||
|
presentation_delay_us,
|
||||||
"📺 HDMI sink queue depth armed"
|
"📺 HDMI sink queue depth armed"
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -184,6 +197,7 @@ impl HdmiSink {
|
|||||||
pipe: pipeline,
|
pipe: pipeline,
|
||||||
next_pts_us: AtomicU64::new(0),
|
next_pts_us: AtomicU64::new(0),
|
||||||
frame_step_us,
|
frame_step_us,
|
||||||
|
presentation_delay_us,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,8 +217,11 @@ impl HdmiSink {
|
|||||||
pub fn push(&self, pkt: VideoPacket) {
|
pub fn push(&self, pkt: VideoPacket) {
|
||||||
let mut buf = gst::Buffer::from_slice(pkt.data);
|
let mut buf = gst::Buffer::from_slice(pkt.data);
|
||||||
if let Some(meta) = buf.get_mut() {
|
if let Some(meta) = buf.get_mut() {
|
||||||
let pts_us =
|
let pts_us = crate::video_support::reserve_local_pts(
|
||||||
crate::video_support::reserve_local_pts(&self.next_pts_us, pkt.pts, self.frame_step_us);
|
&self.next_pts_us,
|
||||||
|
pkt.pts.saturating_add(self.presentation_delay_us),
|
||||||
|
self.frame_step_us,
|
||||||
|
);
|
||||||
let ts = gst::ClockTime::from_useconds(pts_us);
|
let ts = gst::ClockTime::from_useconds(pts_us);
|
||||||
meta.set_pts(Some(ts));
|
meta.set_pts(Some(ts));
|
||||||
meta.set_dts(Some(ts));
|
meta.set_dts(Some(ts));
|
||||||
@ -369,7 +386,7 @@ fn read_bool_env(name: &str) -> Option<bool> {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod hdmi_queue_tests {
|
mod hdmi_queue_tests {
|
||||||
use super::hdmi_queue_buffers;
|
use super::{hdmi_presentation_delay_us, hdmi_queue_buffers};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn hdmi_queue_depth_defaults_to_one_frame() {
|
fn hdmi_queue_depth_defaults_to_one_frame() {
|
||||||
@ -390,4 +407,17 @@ mod hdmi_queue_tests {
|
|||||||
assert_eq!(hdmi_queue_buffers(), 1);
|
assert_eq!(hdmi_queue_buffers(), 1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn hdmi_presentation_delay_defaults_to_measured_holdback_and_accepts_override() {
|
||||||
|
temp_env::with_var_unset("LESAVKA_HDMI_PRESENTATION_DELAY_US", || {
|
||||||
|
assert_eq!(hdmi_presentation_delay_us(), 180_000);
|
||||||
|
});
|
||||||
|
temp_env::with_var("LESAVKA_HDMI_PRESENTATION_DELAY_US", Some("185000"), || {
|
||||||
|
assert_eq!(hdmi_presentation_delay_us(), 185_000);
|
||||||
|
});
|
||||||
|
temp_env::with_var("LESAVKA_HDMI_PRESENTATION_DELAY_US", Some("nope"), || {
|
||||||
|
assert_eq!(hdmi_presentation_delay_us(), 180_000);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user