Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Utils & snippets for manually logged VideoFrameReference #7403

Merged
merged 6 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ namespace rerun.archetypes;
/// Follow <https://github.com/rerun-io/rerun/issues/7298> for updates on the native support.
///
/// In order to display a video, you need to log a [archetypes.VideoFrameReference] for each frame.
// TODO(#7368): More docs and examples on how to use this.
///
/// \example archetypes/video_manual_frames title="Video with explicit frames" image="https://static.rerun.io/video_manual_frames/320a44e1e06b8b3a3161ecbbeae3e04d1ccb9589/1200w.png"
// TODO(#7368): Example and reference to `send_video_frames` API.
table AssetVideo (
"attr.rerun.experimental"
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ namespace rerun.archetypes;

/// References a single video frame.
///
/// Used to display video frames from a [archetypes.AssetVideo].
// TODO(#7368): More docs and examples on how to use this.
/// Used to display individual video frames from a [archetypes.AssetVideo].
/// To show an entire video, a fideo frame reference for each frame of the video should be logged.
///
/// \example archetypes/video_manual_frames title="Video with explicit frames" image="https://static.rerun.io/video_manual_frames/320a44e1e06b8b3a3161ecbbeae3e04d1ccb9589/1200w.png"
// TODO(#7368): Example and reference to `send_video_frames` API.
table VideoFrameReference (
"attr.rerun.experimental"
){
Expand All @@ -22,5 +25,9 @@ table VideoFrameReference (
/// If none is specified, the video is assumed to be at the same entity.
/// Note that blueprint overrides on the referenced video will be ignored regardless,
/// as this is always interpreted as a reference to the data store.
///
/// For a series of video frame references, it is recommended to specify this path only once
/// at the beginning of the series and then rely on latest-at query semantics to
/// keep the video reference active.
video_reference: rerun.components.EntityPath ("attr.rerun.component_optional", nullable, order: 2000);
}
52 changes: 52 additions & 0 deletions crates/store/re_types/src/archetypes/asset_video.rs

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

63 changes: 62 additions & 1 deletion crates/store/re_types/src/archetypes/video_frame_reference.rs

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

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: 1 addition & 1 deletion crates/viewer/re_viewer/src/reflection/mod.rs

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

14 changes: 14 additions & 0 deletions docs/content/reference/types/archetypes/asset_video.md

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

17 changes: 16 additions & 1 deletion docs/content/reference/types/archetypes/video_frame_reference.md

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

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
50 changes: 50 additions & 0 deletions docs/snippets/all/archetypes/video_manual_frames.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// 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]);
}
auto video_frame_reference_indicators =
rerun::ComponentColumn::from_indicators<rerun::VideoFrameReference>(
static_cast<uint32_t>(times.size())
);
rec.send_columns(
"video",
rerun::TimeColumn::from_times("video_time", rerun::borrow(times)),
{
video_frame_reference_indicators.value_or_throw(),
rerun::ComponentColumn::from_loggable(rerun::borrow(video_timestamps)).value_or_throw(),
}
);
}
Loading
Loading