diff --git a/media-utils/video2rrd/Cargo.toml b/media-utils/video2rrd/Cargo.toml
index 1c11cea88..ccf43b2be 100644
--- a/media-utils/video2rrd/Cargo.toml
+++ b/media-utils/video2rrd/Cargo.toml
@@ -19,6 +19,11 @@ ndarray = "0.15.6"
machine-vision-formats = "0.1.1"
rayon = "1.9.0"
opencv = { version = "0.88.8", optional = true }
+chrono = { version = "0.4.38", features = [
+ "libc",
+ "serde",
+ "std",
+], default-features = false }
env-tracing-logger = { path = "../../env-tracing-logger" }
convert-image = { path = "../../convert-image" }
diff --git a/media-utils/video2rrd/src/main.rs b/media-utils/video2rrd/src/main.rs
index c49688a37..839361e89 100644
--- a/media-utils/video2rrd/src/main.rs
+++ b/media-utils/video2rrd/src/main.rs
@@ -25,6 +25,16 @@ struct Opt {
/// Output rrd filename. Defaults to ".rrd"
#[arg(short, long)]
output: Option,
+
+ /// Start time of the video. By default, this will be read from the video itself.
+ #[arg(short, long)]
+ start_time: Option>,
+
+ /// Force the video to be interpreted as having this frame rate (in frames per second).
+ ///
+ /// By default, timestamps in the video itself will be used.
+ #[arg(short, long)]
+ framerate: Option,
}
fn to_rr_image(im: ImageData) -> eyre::Result {
@@ -97,7 +107,17 @@ fn main() -> eyre::Result<()> {
};
tracing::info!("Frame size: {}x{}", src.width(), src.height());
- let start_time = src.frame0_time().unwrap();
+
+ let start_time = if let Some(t) = opt.start_time.as_ref() {
+ t.clone()
+ } else {
+ src.frame0_time().ok_or_else(|| {
+ eyre::eyre!(
+ "video start time could not be determined from the \
+ video, nor was it specified on the command line."
+ )
+ })?
+ };
// let frametimes = self.frametimes.get(&cam_data.camn).unwrap();
// let (data2d_fnos, data2d_stamps): (Vec, Vec) = frametimes.iter().cloned().unzip();
@@ -112,12 +132,20 @@ fn main() -> eyre::Result<()> {
.save(&output)
.wrap_err_with(|| format!("Creating output file {}", output.display()))?;
- for frame in src.iter() {
+ for (fno, frame) in src.iter().enumerate() {
let frame = frame?;
- let pts = match frame.timestamp() {
- Timestamp::Duration(pts) => pts,
- _ => {
- eyre::bail!("video has no PTS timestamps.");
+ let pts = if let Some(forced_framerate) = opt.framerate.as_ref() {
+ let elapsed_secs = fno as f64 / forced_framerate;
+ std::time::Duration::from_secs_f64(elapsed_secs)
+ } else {
+ match frame.timestamp() {
+ Timestamp::Duration(pts) => pts,
+ _ => {
+ eyre::bail!(
+ "video has no PTS timestamps and framerate was not \
+ specified on the command line."
+ );
+ }
}
};