Skip to content

Commit

Permalink
Add examples for manual logging of video reference + needed extension…
Browse files Browse the repository at this point in the history
…s etc.
  • Loading branch information
Wumpf committed Sep 11, 2024
1 parent 51a4019 commit 148f9fc
Show file tree
Hide file tree
Showing 18 changed files with 334 additions and 60 deletions.
2 changes: 1 addition & 1 deletion crates/store/re_data_loader/src/loader_archetype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ fn load_video(
.flat_map(|segment| {
segment.samples.iter().map(|s| {
// TODO(andreas): Use sample indices instead of timestamps once possible.
re_types::components::VideoTimestamp::new_nanoseconds(
re_types::components::VideoTimestamp::from_nanoseconds(
s.timestamp.as_nanoseconds(),
)
})
Expand Down
16 changes: 14 additions & 2 deletions crates/store/re_types/src/components/video_timestamp_ext.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
use super::VideoTimestamp;

impl VideoTimestamp {
/// Create new timestamp from seconds since video start.
#[inline]
pub fn from_seconds(seconds: f64) -> Self {
crate::datatypes::VideoTimestamp::from_nanoseconds((seconds * 1e9) as i64).into()
}

/// Create new timestamp from milliseconds since video start.
#[inline]
pub fn from_milliseconds(milliseconds: f64) -> Self {
crate::datatypes::VideoTimestamp::from_nanoseconds((milliseconds * 1e6) as i64).into()
}

/// Create new timestamp from nanoseconds since video start.
#[inline]
pub fn new_nanoseconds(nanos: i64) -> Self {
crate::datatypes::VideoTimestamp::new_nanoseconds(nanos).into()
pub fn from_nanoseconds(nanos: i64) -> Self {
crate::datatypes::VideoTimestamp::from_nanoseconds(nanos).into()
}
}
2 changes: 1 addition & 1 deletion crates/store/re_types/src/datatypes/video_timestamp_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use super::{VideoTimeMode, VideoTimestamp};
impl VideoTimestamp {
/// Create new timestamp from nanoseconds since video start.
#[inline]
pub fn new_nanoseconds(nanos: i64) -> Self {
pub fn from_nanoseconds(nanos: i64) -> Self {
Self {
video_time: nanos,
time_mode: VideoTimeMode::Nanoseconds,
Expand Down
43 changes: 43 additions & 0 deletions crates/store/re_types_core/src/archetype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,18 @@ impl<A: Archetype> GenericIndicatorComponent<A> {
pub const DEFAULT: Self = Self {
_phantom: std::marker::PhantomData::<A>,
};

/// Create an array of indicator components of this type with the given length.
///
/// This can be useful when sending columns of indicators with
/// `rerun::RecordingStream::send_columns`.
#[inline]
pub fn new_array(len: usize) -> GenericIndicatorComponentArray<A> {
GenericIndicatorComponentArray {
len,
_phantom: std::marker::PhantomData::<A>,
}
}
}

impl<A: Archetype> Default for GenericIndicatorComponent<A> {
Expand Down Expand Up @@ -221,6 +233,37 @@ impl<A: Archetype> crate::LoggableBatch for GenericIndicatorComponent<A> {

impl<A: Archetype> crate::ComponentBatch for GenericIndicatorComponent<A> {}

/// A generic [indicator component] array of a given length.
///
/// This can be useful when sending columns of indicators with
/// `rerun::RecordingStream::send_columns`.
///
/// To create this type, call [`GenericIndicatorComponent::new_array`].
///
/// [indicator component]: [`Archetype::Indicator`]
#[derive(Debug, Clone, Copy)]
pub struct GenericIndicatorComponentArray<A: Archetype> {
len: usize,
_phantom: std::marker::PhantomData<A>,
}

impl<A: Archetype> crate::LoggableBatch for GenericIndicatorComponentArray<A> {
type Name = ComponentName;

#[inline]
fn name(&self) -> Self::Name {
GenericIndicatorComponent::<A>::DEFAULT.name()
}

#[inline]
fn to_arrow(&self) -> SerializationResult<Box<dyn arrow2::array::Array>> {
let datatype = arrow2::datatypes::DataType::Null;
Ok(arrow2::array::NullArray::new(datatype, self.len).boxed())
}
}

impl<A: Archetype> crate::ComponentBatch for GenericIndicatorComponentArray<A> {}

// ---

/// An arbitrary named [indicator component].
Expand Down
2 changes: 0 additions & 2 deletions docs/snippets/all/archetypes/asset3d_simple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

#include <rerun.hpp>

#include <filesystem>
#include <iostream>
#include <string>

int main(int argc, char* argv[]) {
if (argc < 2) {
Expand Down
47 changes: 47 additions & 0 deletions docs/snippets/all/archetypes/video_manual_frames.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Log a video asset using manually created frame references.
// TODO(#7298): ⚠️ Video is currently only supported in the Rerun web viewer.

#include <rerun.hpp>

#include <iostream>

using namespace std::chrono_literals;

int main(int argc, char* argv[]) {
if (argc < 2) {
// TODO(#7354): Only mp4 is supported for now.
std::cerr << "Usage: " << argv[0] << " <path_to_video.[mp4]>" << std::endl;
return 1;
}

const auto path = argv[1];

const auto rec = rerun::RecordingStream("rerun_example_asset_video_manual_frames");
rec.spawn().exit_on_failure();

// Log video asset which is referred to by frame references.
// Make sure it's available on the timeline used for the frame references.
rec.set_time_seconds("video_time", 0.0);
rec.log("video", rerun::AssetVideo::from_file(path).value_or_throw());

// Send frame references for every 0.1 seconds over a total of 10 seconds.
// Naturally, this will result in a choppy playback and only makes sense if the video is 10 seconds or longer.
// TODO(#7368): Point to example using `send_video_frames`.
//
// Use `send_columns` to send all frame references in a single call.
std::vector<std::chrono::milliseconds> times(10 * 10);
std::vector<rerun::components::VideoTimestamp> video_timestamps(10 * 10);
for (size_t i = 0; i < times.size(); i++) {
times[i] = 100ms * i;
video_timestamps[i] = rerun::components::VideoTimestamp(times[i]);
}
rec.send_columns(
"video",
rerun::TimeColumn::from_times("video_time", rerun::borrow(times)),
{
rerun::ComponentColumn::from_indicators<rerun::VideoFrameReference>(times.size())
.value_or_throw(),
rerun::ComponentColumn::from_loggable(rerun::borrow(video_timestamps)).value_or_throw(),
}
);
}
33 changes: 33 additions & 0 deletions docs/snippets/all/archetypes/video_manual_frames.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""
Log a video asset using manually created frame references.
TODO(#7298): ⚠️ Video is currently only supported in the Rerun web viewer.
"""

import sys

import rerun as rr
import numpy as np

if len(sys.argv) < 2:
# TODO(#7354): Only mp4 is supported for now.
print(f"Usage: {sys.argv[0]} <path_to_video.[mp4]>")
sys.exit(1)

rr.init("rerun_example_asset_video_manual_frames", spawn=True)

# Log video asset which is referred to by frame references.
rr.set_time_seconds("video_time", 0) # Make sure it's available on the timeline used for the frame references.
rr.log("video", rr.AssetVideo(path=sys.argv[1]))

# Send frame references for every 0.1 seconds over a total of 10 seconds.
# Naturally, this will result in a choppy playback and only makes sense if the video is 10 seconds or longer.
# TODO(#7368): Point to example using `send_video_frames`.
#
# Use `send_columns` to send all frame references in a single call.
times = np.arange(0.0, 10.0, 0.1)
rr.send_columns(
"video",
times=[rr.TimeSecondsColumn("video_time", times)],
components=[rr.VideoFrameReference.indicator(), rr.components.VideoTimestamp.seconds(times)],
)
40 changes: 40 additions & 0 deletions docs/snippets/all/archetypes/video_manual_frames.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//! Log a video asset using manually created frame references.
//! TODO(#7298): ⚠️ Video is currently only supported in the Rerun web viewer.
use rerun::{external::anyhow, TimeColumn};

fn main() -> anyhow::Result<()> {
let args = _args;
let Some(path) = args.get(1) else {
// TODO(#7354): Only mp4 is supported for now.
anyhow::bail!("Usage: {} <path_to_video.[mp4]>", args[0]);
};

let rec =
rerun::RecordingStreamBuilder::new("rerun_example_asset_video_manual_frames").spawn()?;

// Log video asset which is referred to by frame references.
rec.set_time_seconds("video_time", 0.0); // Make sure it's available on the timeline used for the frame references.
rec.log("video", &rerun::AssetVideo::from_file_path(path)?)?;

// Send frame references for every 0.1 seconds over a total of 10 seconds.
// Naturally, this will result in a choppy playback and only makes sense if the video is 10 seconds or longer.
// TODO(#7368): Point to example using `send_video_frames`.
//
// Use `send_columns` to send all frame references in a single call.
let times = (0..(10 * 10)).map(|t| t as f64 * 0.1).collect::<Vec<_>>();
let time_column = TimeColumn::new_seconds("video_time", times.iter().copied());
let frame_reference_indicators =
<rerun::VideoFrameReference as rerun::Archetype>::Indicator::new_array(times.len());
let video_timestamps = times
.into_iter()
.map(rerun::components::VideoTimestamp::from_seconds)
.collect::<Vec<_>>();
rec.send_columns(
"video",
[time_column],
[&frame_reference_indicators as _, &video_timestamps as _],
)?;

Ok(())
}
21 changes: 0 additions & 21 deletions docs/snippets/all/archetypes/video_simple.cpp

This file was deleted.

13 changes: 0 additions & 13 deletions docs/snippets/all/archetypes/video_simple.py

This file was deleted.

16 changes: 0 additions & 16 deletions docs/snippets/all/archetypes/video_simple.rs

This file was deleted.

4 changes: 3 additions & 1 deletion docs/snippets/snippets.toml
Original file line number Diff line number Diff line change
Expand Up @@ -188,4 +188,6 @@ quick_start = [ # These examples don't have exactly the same implementation.
[extra_args]
"archetypes/asset3d_simple" = ["$config_dir/../../tests/assets/cube.glb"]
"archetypes/asset3d_out_of_tree" = ["$config_dir/../../tests/assets/cube.glb"]
"archetypes/video_simple" = ["$config_dir/../../tests/assets/empty.mp4"]
"archetypes/video_manual_frames" = [
"$config_dir/../../tests/assets/video/Big_Buck_Bunny_1080_10s_av1.mp4",
]
2 changes: 0 additions & 2 deletions rerun_cpp/src/rerun/archetypes/asset3d.hpp

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 34 additions & 0 deletions rerun_cpp/src/rerun/components/video_timestamp.hpp

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 148f9fc

Please sign in to comment.