From 771d49a5072fbb5baa9b65a07803d5339f7e58ca Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Wed, 11 Sep 2024 19:09:28 +0200 Subject: [PATCH 1/6] Add examples for manual logging of video reference + needed extensions etc. --- .../re_data_loader/src/loader_archetype.rs | 2 +- .../src/components/video_timestamp_ext.rs | 16 ++++- .../src/datatypes/video_timestamp_ext.rs | 2 +- crates/store/re_types_core/src/archetype.rs | 43 ++++++++++++ .../all/archetypes/asset3d_simple.cpp | 2 - .../all/archetypes/video_manual_frames.cpp | 47 ++++++++++++++ .../all/archetypes/video_manual_frames.py | 33 ++++++++++ .../all/archetypes/video_manual_frames.rs | 40 ++++++++++++ docs/snippets/all/archetypes/video_simple.cpp | 21 ------ docs/snippets/all/archetypes/video_simple.py | 13 ---- docs/snippets/all/archetypes/video_simple.rs | 16 ----- docs/snippets/snippets.toml | 4 +- rerun_cpp/src/rerun/archetypes/asset3d.hpp | 2 - .../src/rerun/components/video_timestamp.hpp | 34 ++++++++++ .../rerun/components/video_timestamp_ext.cpp | 50 ++++++++++++++ rerun_py/rerun_sdk/rerun/__init__.py | 1 + .../rerun/components/video_timestamp.py | 3 +- .../rerun/components/video_timestamp_ext.py | 65 +++++++++++++++++++ 18 files changed, 334 insertions(+), 60 deletions(-) create mode 100644 docs/snippets/all/archetypes/video_manual_frames.cpp create mode 100644 docs/snippets/all/archetypes/video_manual_frames.py create mode 100644 docs/snippets/all/archetypes/video_manual_frames.rs delete mode 100644 docs/snippets/all/archetypes/video_simple.cpp delete mode 100755 docs/snippets/all/archetypes/video_simple.py delete mode 100644 docs/snippets/all/archetypes/video_simple.rs create mode 100644 rerun_cpp/src/rerun/components/video_timestamp_ext.cpp create mode 100644 rerun_py/rerun_sdk/rerun/components/video_timestamp_ext.py diff --git a/crates/store/re_data_loader/src/loader_archetype.rs b/crates/store/re_data_loader/src/loader_archetype.rs index 6f29163ef7b6..e1433b7f54f3 100644 --- a/crates/store/re_data_loader/src/loader_archetype.rs +++ b/crates/store/re_data_loader/src/loader_archetype.rs @@ -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(), ) }) diff --git a/crates/store/re_types/src/components/video_timestamp_ext.rs b/crates/store/re_types/src/components/video_timestamp_ext.rs index df7a6f9947bc..48efa5617d5e 100644 --- a/crates/store/re_types/src/components/video_timestamp_ext.rs +++ b/crates/store/re_types/src/components/video_timestamp_ext.rs @@ -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() } } diff --git a/crates/store/re_types/src/datatypes/video_timestamp_ext.rs b/crates/store/re_types/src/datatypes/video_timestamp_ext.rs index 342e0d1051db..4e17ee943174 100644 --- a/crates/store/re_types/src/datatypes/video_timestamp_ext.rs +++ b/crates/store/re_types/src/datatypes/video_timestamp_ext.rs @@ -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, diff --git a/crates/store/re_types_core/src/archetype.rs b/crates/store/re_types_core/src/archetype.rs index d00e2792f0d6..6eef97eb8176 100644 --- a/crates/store/re_types_core/src/archetype.rs +++ b/crates/store/re_types_core/src/archetype.rs @@ -194,6 +194,18 @@ impl GenericIndicatorComponent { pub const DEFAULT: Self = Self { _phantom: std::marker::PhantomData::, }; + + /// 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 { + GenericIndicatorComponentArray { + len, + _phantom: std::marker::PhantomData::, + } + } } impl Default for GenericIndicatorComponent { @@ -221,6 +233,37 @@ impl crate::LoggableBatch for GenericIndicatorComponent { impl crate::ComponentBatch for GenericIndicatorComponent {} +/// 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 { + len: usize, + _phantom: std::marker::PhantomData, +} + +impl crate::LoggableBatch for GenericIndicatorComponentArray { + type Name = ComponentName; + + #[inline] + fn name(&self) -> Self::Name { + GenericIndicatorComponent::::DEFAULT.name() + } + + #[inline] + fn to_arrow(&self) -> SerializationResult> { + let datatype = arrow2::datatypes::DataType::Null; + Ok(arrow2::array::NullArray::new(datatype, self.len).boxed()) + } +} + +impl crate::ComponentBatch for GenericIndicatorComponentArray {} + // --- /// An arbitrary named [indicator component]. diff --git a/docs/snippets/all/archetypes/asset3d_simple.cpp b/docs/snippets/all/archetypes/asset3d_simple.cpp index 1689e792ef26..9d2c9893983b 100644 --- a/docs/snippets/all/archetypes/asset3d_simple.cpp +++ b/docs/snippets/all/archetypes/asset3d_simple.cpp @@ -2,9 +2,7 @@ #include -#include #include -#include int main(int argc, char* argv[]) { if (argc < 2) { diff --git a/docs/snippets/all/archetypes/video_manual_frames.cpp b/docs/snippets/all/archetypes/video_manual_frames.cpp new file mode 100644 index 000000000000..2c54634cca5d --- /dev/null +++ b/docs/snippets/all/archetypes/video_manual_frames.cpp @@ -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 + +#include + +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] << " " << 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 times(10 * 10); + std::vector 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(times.size()) + .value_or_throw(), + rerun::ComponentColumn::from_loggable(rerun::borrow(video_timestamps)).value_or_throw(), + } + ); +} diff --git a/docs/snippets/all/archetypes/video_manual_frames.py b/docs/snippets/all/archetypes/video_manual_frames.py new file mode 100644 index 000000000000..e515c337ef52 --- /dev/null +++ b/docs/snippets/all/archetypes/video_manual_frames.py @@ -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]} ") + 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)], +) diff --git a/docs/snippets/all/archetypes/video_manual_frames.rs b/docs/snippets/all/archetypes/video_manual_frames.rs new file mode 100644 index 000000000000..24e7f25fe799 --- /dev/null +++ b/docs/snippets/all/archetypes/video_manual_frames.rs @@ -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: {} ", 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::>(); + let time_column = TimeColumn::new_seconds("video_time", times.iter().copied()); + let frame_reference_indicators = + ::Indicator::new_array(times.len()); + let video_timestamps = times + .into_iter() + .map(rerun::components::VideoTimestamp::from_seconds) + .collect::>(); + rec.send_columns( + "video", + [time_column], + [&frame_reference_indicators as _, &video_timestamps as _], + )?; + + Ok(()) +} diff --git a/docs/snippets/all/archetypes/video_simple.cpp b/docs/snippets/all/archetypes/video_simple.cpp deleted file mode 100644 index 82907b9ed920..000000000000 --- a/docs/snippets/all/archetypes/video_simple.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// Log a video file. - -#include - -#include -#include -#include - -int main(int argc, char* argv[]) { - if (argc < 2) { - std::cerr << "Usage: " << argv[0] << " " << std::endl; - return 1; - } - - const auto path = argv[1]; - - const auto rec = rerun::RecordingStream("rerun_example_asset_video"); - rec.spawn().exit_on_failure(); - - rec.log("world/video", rerun::AssetVideo::from_file(path).value_or_throw()); -} diff --git a/docs/snippets/all/archetypes/video_simple.py b/docs/snippets/all/archetypes/video_simple.py deleted file mode 100755 index a4ef1ac7fe28..000000000000 --- a/docs/snippets/all/archetypes/video_simple.py +++ /dev/null @@ -1,13 +0,0 @@ -"""Log a video file.""" - -import sys - -import rerun as rr - -if len(sys.argv) < 2: - print(f"Usage: {sys.argv[0]} ") - sys.exit(1) - -rr.init("rerun_example_asset_video", spawn=True) - -rr.log("world/video", rr.AssetVideo(path=sys.argv[1])) diff --git a/docs/snippets/all/archetypes/video_simple.rs b/docs/snippets/all/archetypes/video_simple.rs deleted file mode 100644 index 19abd3f95446..000000000000 --- a/docs/snippets/all/archetypes/video_simple.rs +++ /dev/null @@ -1,16 +0,0 @@ -//! Log a video file. - -use rerun::external::anyhow; - -fn main() -> anyhow::Result<()> { - let args = std::env::args().collect::>(); - let Some(path) = args.get(1) else { - anyhow::bail!("Usage: {} ", args[0]); - }; - - let rec = rerun::RecordingStreamBuilder::new("rerun_example_asset_video").spawn()?; - - rec.log("world/video", &rerun::AssetVideo::from_file_path(path)?)?; - - Ok(()) -} diff --git a/docs/snippets/snippets.toml b/docs/snippets/snippets.toml index 535a82f4ca31..2be554f6a1bd 100644 --- a/docs/snippets/snippets.toml +++ b/docs/snippets/snippets.toml @@ -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", +] diff --git a/rerun_cpp/src/rerun/archetypes/asset3d.hpp b/rerun_cpp/src/rerun/archetypes/asset3d.hpp index 8ce9db4f95cf..812cf71eacb9 100644 --- a/rerun_cpp/src/rerun/archetypes/asset3d.hpp +++ b/rerun_cpp/src/rerun/archetypes/asset3d.hpp @@ -33,9 +33,7 @@ namespace rerun::archetypes { /// ```cpp /// #include /// - /// #include /// #include - /// #include /// /// int main(int argc, char* argv[]) { /// if (argc <2) { diff --git a/rerun_cpp/src/rerun/components/video_timestamp.hpp b/rerun_cpp/src/rerun/components/video_timestamp.hpp index 7a09d14eba53..446208a9f981 100644 --- a/rerun_cpp/src/rerun/components/video_timestamp.hpp +++ b/rerun_cpp/src/rerun/components/video_timestamp.hpp @@ -6,6 +6,7 @@ #include "../datatypes/video_timestamp.hpp" #include "../result.hpp" +#include #include #include @@ -16,6 +17,39 @@ namespace rerun::components { struct VideoTimestamp { rerun::datatypes::VideoTimestamp timestamp; + public: // START of extensions from video_timestamp_ext.cpp: + /// Creates a new `VideoTimestamp` component. + /// \param video_time Timestamp value, type defined by `time_mode`. + /// \param time_mode How to interpret `video_time`. + VideoTimestamp(int64_t video_time, rerun::datatypes::VideoTimeMode time_mode) + : VideoTimestamp(rerun::datatypes::VideoTimestamp{video_time, time_mode}) {} + + /// Creates a new `VideoTimestamp` from time since video start. + /// \param time Time since video start. + template + VideoTimestamp(std::chrono::duration time) + : VideoTimestamp( + std::chrono::duration_cast(time).count(), + datatypes::VideoTimeMode::Nanoseconds + ) {} + + /// Creates a new [`VideoTimestamp`] from seconds since video start. + static VideoTimestamp from_seconds(double seconds) { + return VideoTimestamp(std::chrono::duration(seconds)); + } + + /// Creates a new [`VideoTimestamp`] from milliseconds since video start. + static VideoTimestamp from_milliseconds(double milliseconds) { + return VideoTimestamp(std::chrono::duration(milliseconds)); + } + + /// Creates a new [`VideoTimestamp`] from nanoseconds since video start. + static VideoTimestamp from_nanoseconds(int64_t nanoseconds) { + return VideoTimestamp(std::chrono::nanoseconds(nanoseconds)); + } + + // END of extensions from video_timestamp_ext.cpp, start of generated code: + public: VideoTimestamp() = default; diff --git a/rerun_cpp/src/rerun/components/video_timestamp_ext.cpp b/rerun_cpp/src/rerun/components/video_timestamp_ext.cpp new file mode 100644 index 000000000000..d00165c231b0 --- /dev/null +++ b/rerun_cpp/src/rerun/components/video_timestamp_ext.cpp @@ -0,0 +1,50 @@ +#if 0 + +// +#include +// + +#include "../datatypes/video_time_mode.hpp" +#include "video_timestamp.hpp" + +namespace rerun { + namespace components { + + // + + /// Creates a new `VideoTimestamp` component. + /// \param video_time Timestamp value, type defined by `time_mode`. + /// \param time_mode How to interpret `video_time`. + VideoTimestamp(int64_t video_time, rerun::datatypes::VideoTimeMode time_mode) + : VideoTimestamp(rerun::datatypes::VideoTimestamp{video_time, time_mode}) {} + + /// Creates a new `VideoTimestamp` from time since video start. + /// \param time Time since video start. + template + VideoTimestamp(std::chrono::duration time) + : VideoTimestamp( + std::chrono::duration_cast(time).count(), + datatypes::VideoTimeMode::Nanoseconds + ) {} + + /// Creates a new [`VideoTimestamp`] from seconds since video start. + static VideoTimestamp from_seconds(double seconds) { + return VideoTimestamp(std::chrono::duration(seconds)); + } + + /// Creates a new [`VideoTimestamp`] from milliseconds since video start. + static VideoTimestamp from_milliseconds(double milliseconds) { + return VideoTimestamp(std::chrono::duration(milliseconds)); + } + + /// Creates a new [`VideoTimestamp`] from nanoseconds since video start. + static VideoTimestamp from_nanoseconds(int64_t nanoseconds) { + return VideoTimestamp(std::chrono::nanoseconds(nanoseconds)); + } + + // + + } // namespace components +} // namespace rerun + +#endif diff --git a/rerun_py/rerun_sdk/rerun/__init__.py b/rerun_py/rerun_sdk/rerun/__init__.py index c40e195a7fae..05856117a542 100644 --- a/rerun_py/rerun_sdk/rerun/__init__.py +++ b/rerun_py/rerun_sdk/rerun/__init__.py @@ -79,6 +79,7 @@ TextDocument as TextDocument, TextLog as TextLog, Transform3D as Transform3D, + VideoFrameReference as VideoFrameReference, ViewCoordinates as ViewCoordinates, ) from .archetypes.boxes2d_ext import ( diff --git a/rerun_py/rerun_sdk/rerun/components/video_timestamp.py b/rerun_py/rerun_sdk/rerun/components/video_timestamp.py index 433fe013f8cc..23b11eae4ddc 100644 --- a/rerun_py/rerun_sdk/rerun/components/video_timestamp.py +++ b/rerun_py/rerun_sdk/rerun/components/video_timestamp.py @@ -10,11 +10,12 @@ ComponentBatchMixin, ComponentMixin, ) +from .video_timestamp_ext import VideoTimestampExt __all__ = ["VideoTimestamp", "VideoTimestampBatch", "VideoTimestampType"] -class VideoTimestamp(datatypes.VideoTimestamp, ComponentMixin): +class VideoTimestamp(VideoTimestampExt, datatypes.VideoTimestamp, ComponentMixin): """ **Component**: Timestamp inside a [`archetypes.AssetVideo`][rerun.archetypes.AssetVideo]. diff --git a/rerun_py/rerun_sdk/rerun/components/video_timestamp_ext.py b/rerun_py/rerun_sdk/rerun/components/video_timestamp_ext.py new file mode 100644 index 000000000000..348e8730e5d6 --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/components/video_timestamp_ext.py @@ -0,0 +1,65 @@ +from __future__ import annotations + +import numpy as np +import numpy.typing as npt + +from .. import components, datatypes + + +class VideoTimestampExt: + """Extension for [VideoTimestamp][rerun.components.VideoTimestamp].""" + + # Implementation note: + # We could add an init method that deals with seconds/milliseconds/nanoseconds etc. + # However, this would require _a lot_ of slow parameter validation on a per timestamp basis. + # When in actuallity, this data practifally always comes in homogenous batches. + + @staticmethod + def seconds( + seconds: npt.ArrayLike, + ) -> components.VideoTimestampBatch: + """ + Create a video timestamp batch from seconds since video start. + + Parameters + ---------- + seconds: + Timestamp values in seconds since video start. + + """ + return components.VideoTimestamp.nanoseconds(np.array(seconds) * 1e9) + + @staticmethod + def milliseconds( + milliseconds: npt.ArrayLike, + ) -> components.VideoTimestampBatch: + """ + Create a video timestamp batch from milliseconds since video start. + + Parameters + ---------- + milliseconds: + Timestamp values in milliseconds since video start. + + """ + return components.VideoTimestamp.nanoseconds(np.array(milliseconds) * 1e6) + + @staticmethod + def nanoseconds( + nanoseconds: npt.ArrayLike, + ) -> components.VideoTimestampBatch: + """ + Create a video timestamp batch from nanoseconds since video start. + + Parameters + ---------- + nanoseconds: + Timestamp values in milliseconds since video start. + + """ + nanoseconds = np.asarray(nanoseconds, dtype=np.int64) + + return components.VideoTimestampBatch([ + components.VideoTimestamp(video_time=ns, time_mode=datatypes.VideoTimeMode.Nanoseconds) + for ns in nanoseconds + ]) From 8d4ad66e0c5d9e80f447371b63d03443df4cf7c8 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Thu, 12 Sep 2024 10:10:45 +0200 Subject: [PATCH 2/6] reference new example on video asset and video frame reference archetypes --- .../rerun/archetypes/asset_video.fbs | 4 +- .../archetypes/video_frame_reference.fbs | 11 +++- .../re_types/src/archetypes/asset_video.rs | 52 +++++++++++++++ .../src/archetypes/video_frame_reference.rs | 63 ++++++++++++++++++- crates/viewer/re_viewer/src/reflection/mod.rs | 2 +- .../reference/types/archetypes/asset_video.md | 14 +++++ .../types/archetypes/video_frame_reference.md | 17 ++++- .../all/archetypes/video_manual_frames.py | 7 +-- .../src/rerun/archetypes/asset_video.hpp | 52 +++++++++++++++ .../archetypes/video_frame_reference.hpp | 63 ++++++++++++++++++- .../rerun_sdk/rerun/archetypes/asset_video.py | 45 +++++++++++++ .../rerun/archetypes/video_frame_reference.py | 56 ++++++++++++++++- 12 files changed, 373 insertions(+), 13 deletions(-) diff --git a/crates/store/re_types/definitions/rerun/archetypes/asset_video.fbs b/crates/store/re_types/definitions/rerun/archetypes/asset_video.fbs index ed4a1ad95245..7b61fc0f683a 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/asset_video.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/asset_video.fbs @@ -7,7 +7,9 @@ namespace rerun.archetypes; /// Follow 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" ) { diff --git a/crates/store/re_types/definitions/rerun/archetypes/video_frame_reference.fbs b/crates/store/re_types/definitions/rerun/archetypes/video_frame_reference.fbs index 94d7d29e7667..f503867b41bc 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/video_frame_reference.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/video_frame_reference.fbs @@ -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" ){ @@ -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); } diff --git a/crates/store/re_types/src/archetypes/asset_video.rs b/crates/store/re_types/src/archetypes/asset_video.rs index 1133476159b8..ba29d3d91e6f 100644 --- a/crates/store/re_types/src/archetypes/asset_video.rs +++ b/crates/store/re_types/src/archetypes/asset_video.rs @@ -27,6 +27,58 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// In order to display a video, you need to log a [`archetypes::VideoFrameReference`][crate::archetypes::VideoFrameReference] for each frame. /// /// ⚠️ **This type is experimental and may be removed in future versions** +/// +/// ## Example +/// +/// ### Video with explicit frames +/// ```ignore +/// 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: {} ", 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::>(); +/// let time_column = TimeColumn::new_seconds("video_time", times.iter().copied()); +/// let frame_reference_indicators = +/// ::Indicator::new_array(times.len()); +/// let video_timestamps = times +/// .into_iter() +/// .map(rerun::components::VideoTimestamp::from_seconds) +/// .collect::>(); +/// rec.send_columns( +/// "video", +/// [time_column], +/// [&frame_reference_indicators as _, &video_timestamps as _], +/// )?; +/// +/// Ok(()) +/// } +/// ``` +///
+/// +/// +/// +/// +/// +/// +/// +///
#[derive(Clone, Debug)] pub struct AssetVideo { /// The asset's bytes. diff --git a/crates/store/re_types/src/archetypes/video_frame_reference.rs b/crates/store/re_types/src/archetypes/video_frame_reference.rs index a70ca383cb02..aeca145292ea 100644 --- a/crates/store/re_types/src/archetypes/video_frame_reference.rs +++ b/crates/store/re_types/src/archetypes/video_frame_reference.rs @@ -20,9 +20,62 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Archetype**: References a single video frame. /// -/// Used to display video frames from a [`archetypes::AssetVideo`][crate::archetypes::AssetVideo]. +/// Used to display individual video frames from a [`archetypes::AssetVideo`][crate::archetypes::AssetVideo]. +/// To show an entire video, a fideo frame reference for each frame of the video should be logged. /// /// ⚠️ **This type is experimental and may be removed in future versions** +/// +/// ## Example +/// +/// ### Video with explicit frames +/// ```ignore +/// 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: {} ", 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::>(); +/// let time_column = TimeColumn::new_seconds("video_time", times.iter().copied()); +/// let frame_reference_indicators = +/// ::Indicator::new_array(times.len()); +/// let video_timestamps = times +/// .into_iter() +/// .map(rerun::components::VideoTimestamp::from_seconds) +/// .collect::>(); +/// rec.send_columns( +/// "video", +/// [time_column], +/// [&frame_reference_indicators as _, &video_timestamps as _], +/// )?; +/// +/// Ok(()) +/// } +/// ``` +///
+/// +/// +/// +/// +/// +/// +/// +///
#[derive(Clone, Debug)] pub struct VideoFrameReference { /// References the closest video frame to this timestamp. @@ -36,6 +89,10 @@ pub struct 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. pub video_reference: Option, } @@ -192,6 +249,10 @@ impl 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. #[inline] pub fn with_video_reference( mut self, diff --git a/crates/viewer/re_viewer/src/reflection/mod.rs b/crates/viewer/re_viewer/src/reflection/mod.rs index 38617ffe1f4b..a9d93ea9f5a7 100644 --- a/crates/viewer/re_viewer/src/reflection/mod.rs +++ b/crates/viewer/re_viewer/src/reflection/mod.rs @@ -1470,7 +1470,7 @@ fn generate_archetype_reflection() -> ArchetypeReflectionMap { is_required : true, }, ArchetypeFieldReflection { component_name : "rerun.components.EntityPath".into(), display_name : "Video reference", docstring_md : - "Optional reference to an entity with a [`archetypes.AssetVideo`](https://rerun.io/docs/reference/types/archetypes/asset_video).\n\nIf none is specified, the video is assumed to be at the same entity.\nNote that blueprint overrides on the referenced video will be ignored regardless,\nas this is always interpreted as a reference to the data store.\n\n⚠\u{fe0f} **This type is experimental and may be removed in future versions**", + "Optional reference to an entity with a [`archetypes.AssetVideo`](https://rerun.io/docs/reference/types/archetypes/asset_video).\n\nIf none is specified, the video is assumed to be at the same entity.\nNote that blueprint overrides on the referenced video will be ignored regardless,\nas this is always interpreted as a reference to the data store.\n\nFor a series of video frame references, it is recommended to specify this path only once\nat the beginning of the series and then rely on latest-at query semantics to\nkeep the video reference active.\n\n⚠\u{fe0f} **This type is experimental and may be removed in future versions**", is_required : false, }, ], }, diff --git a/docs/content/reference/types/archetypes/asset_video.md b/docs/content/reference/types/archetypes/asset_video.md index 110d10844a8b..4db7fff313df 100644 --- a/docs/content/reference/types/archetypes/asset_video.md +++ b/docs/content/reference/types/archetypes/asset_video.md @@ -25,3 +25,17 @@ In order to display a video, you need to log a [`archetypes.VideoFrameReference` * 🐍 [Python API docs for `AssetVideo`](https://ref.rerun.io/docs/python/stable/common/archetypes#rerun.archetypes.AssetVideo) * 🦀 [Rust API docs for `AssetVideo`](https://docs.rs/rerun/latest/rerun/archetypes/struct.AssetVideo.html) +## Example + +### Video with explicit frames + +snippet: archetypes/video_manual_frames + + + + + + + + + diff --git a/docs/content/reference/types/archetypes/video_frame_reference.md b/docs/content/reference/types/archetypes/video_frame_reference.md index 641e9cbe7d6d..0fe64d88afef 100644 --- a/docs/content/reference/types/archetypes/video_frame_reference.md +++ b/docs/content/reference/types/archetypes/video_frame_reference.md @@ -8,7 +8,8 @@ title: "VideoFrameReference" References a single video frame. -Used to display video frames from a [`archetypes.AssetVideo`](https://rerun.io/docs/reference/types/archetypes/asset_video). +Used to display individual video frames from a [`archetypes.AssetVideo`](https://rerun.io/docs/reference/types/archetypes/asset_video). +To show an entire video, a fideo frame reference for each frame of the video should be logged. ## Components @@ -21,3 +22,17 @@ Used to display video frames from a [`archetypes.AssetVideo`](https://rerun.io/d * 🐍 [Python API docs for `VideoFrameReference`](https://ref.rerun.io/docs/python/stable/common/archetypes#rerun.archetypes.VideoFrameReference) * 🦀 [Rust API docs for `VideoFrameReference`](https://docs.rs/rerun/latest/rerun/archetypes/struct.VideoFrameReference.html) +## Example + +### Video with explicit frames + +snippet: archetypes/video_manual_frames + + + + + + + + + diff --git a/docs/snippets/all/archetypes/video_manual_frames.py b/docs/snippets/all/archetypes/video_manual_frames.py index e515c337ef52..1e0a436b44bc 100644 --- a/docs/snippets/all/archetypes/video_manual_frames.py +++ b/docs/snippets/all/archetypes/video_manual_frames.py @@ -1,8 +1,5 @@ -""" -Log a video asset using manually created frame references. - -TODO(#7298): ⚠️ Video is currently only supported in the Rerun web viewer. -""" +"""Log a video asset using manually created frame references.""" +# TODO(#7298): ⚠️ Video is currently only supported in the Rerun web viewer. import sys diff --git a/rerun_cpp/src/rerun/archetypes/asset_video.hpp b/rerun_cpp/src/rerun/archetypes/asset_video.hpp index d1510a5c8027..2e9295bbca3f 100644 --- a/rerun_cpp/src/rerun/archetypes/asset_video.hpp +++ b/rerun_cpp/src/rerun/archetypes/asset_video.hpp @@ -26,6 +26,58 @@ namespace rerun::archetypes { /// /// In order to display a video, you need to log a `archetypes::VideoFrameReference` for each frame. /// + /// ## Example + /// + /// ### Video with explicit frames + /// ![image](https://static.rerun.io/video_manual_frames/320a44e1e06b8b3a3161ecbbeae3e04d1ccb9589/full.png) + /// + /// ```cpp + /// #include + /// + /// #include + /// + /// 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: " <" < times(10 * 10); + /// std::vector video_timestamps(10 * 10); + /// for (size_t i = 0; i (times.size()) + /// .value_or_throw(), + /// rerun::ComponentColumn::from_loggable(rerun::borrow(video_timestamps)).value_or_throw(), + /// } + /// ); + /// } + /// ``` + /// /// ⚠ **This is an experimental API! It is not fully supported, and is likely to change significantly in future versions.** struct AssetVideo { /// The asset's bytes. diff --git a/rerun_cpp/src/rerun/archetypes/video_frame_reference.hpp b/rerun_cpp/src/rerun/archetypes/video_frame_reference.hpp index ef96331f1a1a..1c12d48c3377 100644 --- a/rerun_cpp/src/rerun/archetypes/video_frame_reference.hpp +++ b/rerun_cpp/src/rerun/archetypes/video_frame_reference.hpp @@ -19,7 +19,60 @@ namespace rerun::archetypes { /// **Archetype**: References a single video frame. /// - /// Used to display video frames from a `archetypes::AssetVideo`. + /// 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 + /// + /// ### Video with explicit frames + /// ![image](https://static.rerun.io/video_manual_frames/320a44e1e06b8b3a3161ecbbeae3e04d1ccb9589/full.png) + /// + /// ```cpp + /// #include + /// + /// #include + /// + /// 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: " <" < times(10 * 10); + /// std::vector video_timestamps(10 * 10); + /// for (size_t i = 0; i (times.size()) + /// .value_or_throw(), + /// rerun::ComponentColumn::from_loggable(rerun::borrow(video_timestamps)).value_or_throw(), + /// } + /// ); + /// } + /// ``` /// /// ⚠ **This is an experimental API! It is not fully supported, and is likely to change significantly in future versions.** struct VideoFrameReference { @@ -34,6 +87,10 @@ namespace rerun::archetypes { /// 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. std::optional video_reference; public: @@ -55,6 +112,10 @@ namespace rerun::archetypes { /// 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. VideoFrameReference with_video_reference(rerun::components::EntityPath _video_reference ) && { video_reference = std::move(_video_reference); diff --git a/rerun_py/rerun_sdk/rerun/archetypes/asset_video.py b/rerun_py/rerun_sdk/rerun/archetypes/asset_video.py index ad3c40e8bd22..1a48bd1bcd3a 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/asset_video.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/asset_video.py @@ -28,6 +28,51 @@ class AssetVideo(AssetVideoExt, Archetype): In order to display a video, you need to log a [`archetypes.VideoFrameReference`][rerun.archetypes.VideoFrameReference] for each frame. ⚠️ **This is an experimental API! It is not fully supported, and is likely to change significantly in future versions.** + + Example + ------- + ### Video with explicit frames: + ```python + # 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]} ") + 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)], + ) + ``` +
+ + + + + + + +
+ """ # __init__ can be found in asset_video_ext.py diff --git a/rerun_py/rerun_sdk/rerun/archetypes/video_frame_reference.py b/rerun_py/rerun_sdk/rerun/archetypes/video_frame_reference.py index d73ff771bdf3..3ebd43d53348 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/video_frame_reference.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/video_frame_reference.py @@ -23,9 +23,55 @@ class VideoFrameReference(Archetype): """ **Archetype**: References a single video frame. - Used to display video frames from a [`archetypes.AssetVideo`][rerun.archetypes.AssetVideo]. + Used to display individual video frames from a [`archetypes.AssetVideo`][rerun.archetypes.AssetVideo]. + To show an entire video, a fideo frame reference for each frame of the video should be logged. ⚠️ **This is an experimental API! It is not fully supported, and is likely to change significantly in future versions.** + + Example + ------- + ### Video with explicit frames: + ```python + # 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]} ") + 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)], + ) + ``` +
+ + + + + + + +
+ """ def __init__( @@ -48,6 +94,10 @@ def __init__( 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. + """ # You can define your own __init__ function as a member of VideoFrameReferenceExt in video_frame_reference_ext.py @@ -92,6 +142,10 @@ def _clear(cls) -> VideoFrameReference: # 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. + # # (Docstring intentionally commented out to hide this field from the docs) __str__ = Archetype.__str__ From 879a9a81881654ed9367a15f961e1b810680d091 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Thu, 12 Sep 2024 10:25:28 +0200 Subject: [PATCH 3/6] typos and python formatting --- docs/snippets/all/archetypes/video_manual_frames.py | 2 +- rerun_py/rerun_sdk/rerun/archetypes/asset_video.py | 2 +- rerun_py/rerun_sdk/rerun/archetypes/video_frame_reference.py | 2 +- rerun_py/rerun_sdk/rerun/components/video_timestamp_ext.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/snippets/all/archetypes/video_manual_frames.py b/docs/snippets/all/archetypes/video_manual_frames.py index 1e0a436b44bc..db69b510dd01 100644 --- a/docs/snippets/all/archetypes/video_manual_frames.py +++ b/docs/snippets/all/archetypes/video_manual_frames.py @@ -3,8 +3,8 @@ import sys -import rerun as rr import numpy as np +import rerun as rr if len(sys.argv) < 2: # TODO(#7354): Only mp4 is supported for now. diff --git a/rerun_py/rerun_sdk/rerun/archetypes/asset_video.py b/rerun_py/rerun_sdk/rerun/archetypes/asset_video.py index 1a48bd1bcd3a..05a7d45aee47 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/asset_video.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/asset_video.py @@ -37,8 +37,8 @@ class AssetVideo(AssetVideoExt, Archetype): import sys - import rerun as rr import numpy as np + import rerun as rr if len(sys.argv) < 2: # TODO(#7354): Only mp4 is supported for now. diff --git a/rerun_py/rerun_sdk/rerun/archetypes/video_frame_reference.py b/rerun_py/rerun_sdk/rerun/archetypes/video_frame_reference.py index 3ebd43d53348..6dba6a947778 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/video_frame_reference.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/video_frame_reference.py @@ -36,8 +36,8 @@ class VideoFrameReference(Archetype): import sys - import rerun as rr import numpy as np + import rerun as rr if len(sys.argv) < 2: # TODO(#7354): Only mp4 is supported for now. diff --git a/rerun_py/rerun_sdk/rerun/components/video_timestamp_ext.py b/rerun_py/rerun_sdk/rerun/components/video_timestamp_ext.py index 348e8730e5d6..fbee654c9c07 100644 --- a/rerun_py/rerun_sdk/rerun/components/video_timestamp_ext.py +++ b/rerun_py/rerun_sdk/rerun/components/video_timestamp_ext.py @@ -12,7 +12,7 @@ class VideoTimestampExt: # Implementation note: # We could add an init method that deals with seconds/milliseconds/nanoseconds etc. # However, this would require _a lot_ of slow parameter validation on a per timestamp basis. - # When in actuallity, this data practifally always comes in homogenous batches. + # When in actuallity, this data practically always comes in homogeneous batches. @staticmethod def seconds( From d56d07c4f802e1381d57f93d17c387dc01212430 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Thu, 12 Sep 2024 11:47:13 +0200 Subject: [PATCH 4/6] fix C++ linux build --- docs/snippets/all/archetypes/video_manual_frames.cpp | 7 +++++-- rerun_cpp/src/rerun/archetypes/asset_video.hpp | 7 +++++-- rerun_cpp/src/rerun/archetypes/video_frame_reference.hpp | 7 +++++-- rerun_cpp/src/rerun/components/video_timestamp.hpp | 6 ++++-- rerun_cpp/src/rerun/components/video_timestamp_ext.cpp | 6 ++++-- 5 files changed, 23 insertions(+), 10 deletions(-) diff --git a/docs/snippets/all/archetypes/video_manual_frames.cpp b/docs/snippets/all/archetypes/video_manual_frames.cpp index 2c54634cca5d..b24fd12eef85 100644 --- a/docs/snippets/all/archetypes/video_manual_frames.cpp +++ b/docs/snippets/all/archetypes/video_manual_frames.cpp @@ -35,12 +35,15 @@ int main(int argc, char* argv[]) { times[i] = 100ms * i; video_timestamps[i] = rerun::components::VideoTimestamp(times[i]); } + auto video_frame_reference_indicators = + rerun::ComponentColumn::from_indicators( + static_cast(times.size()) + ); rec.send_columns( "video", rerun::TimeColumn::from_times("video_time", rerun::borrow(times)), { - rerun::ComponentColumn::from_indicators(times.size()) - .value_or_throw(), + video_frame_reference_indicators.value_or_throw(), rerun::ComponentColumn::from_loggable(rerun::borrow(video_timestamps)).value_or_throw(), } ); diff --git a/rerun_cpp/src/rerun/archetypes/asset_video.hpp b/rerun_cpp/src/rerun/archetypes/asset_video.hpp index 2e9295bbca3f..bc25a1247fe7 100644 --- a/rerun_cpp/src/rerun/archetypes/asset_video.hpp +++ b/rerun_cpp/src/rerun/archetypes/asset_video.hpp @@ -66,12 +66,15 @@ namespace rerun::archetypes { /// times[i] = 100ms * i; /// video_timestamps[i] = rerun::components::VideoTimestamp(times[i]); /// } + /// auto video_frame_reference_indicators = + /// rerun::ComponentColumn::from_indicators( + /// static_cast(times.size()) + /// ); /// rec.send_columns( /// "video", /// rerun::TimeColumn::from_times("video_time", rerun::borrow(times)), /// { - /// rerun::ComponentColumn::from_indicators(times.size()) - /// .value_or_throw(), + /// video_frame_reference_indicators.value_or_throw(), /// rerun::ComponentColumn::from_loggable(rerun::borrow(video_timestamps)).value_or_throw(), /// } /// ); diff --git a/rerun_cpp/src/rerun/archetypes/video_frame_reference.hpp b/rerun_cpp/src/rerun/archetypes/video_frame_reference.hpp index 1c12d48c3377..814baed5c996 100644 --- a/rerun_cpp/src/rerun/archetypes/video_frame_reference.hpp +++ b/rerun_cpp/src/rerun/archetypes/video_frame_reference.hpp @@ -62,12 +62,15 @@ namespace rerun::archetypes { /// times[i] = 100ms * i; /// video_timestamps[i] = rerun::components::VideoTimestamp(times[i]); /// } + /// auto video_frame_reference_indicators = + /// rerun::ComponentColumn::from_indicators( + /// static_cast(times.size()) + /// ); /// rec.send_columns( /// "video", /// rerun::TimeColumn::from_times("video_time", rerun::borrow(times)), /// { - /// rerun::ComponentColumn::from_indicators(times.size()) - /// .value_or_throw(), + /// video_frame_reference_indicators.value_or_throw(), /// rerun::ComponentColumn::from_loggable(rerun::borrow(video_timestamps)).value_or_throw(), /// } /// ); diff --git a/rerun_cpp/src/rerun/components/video_timestamp.hpp b/rerun_cpp/src/rerun/components/video_timestamp.hpp index 446208a9f981..00d6a5aaacc6 100644 --- a/rerun_cpp/src/rerun/components/video_timestamp.hpp +++ b/rerun_cpp/src/rerun/components/video_timestamp.hpp @@ -21,8 +21,10 @@ namespace rerun::components { /// Creates a new `VideoTimestamp` component. /// \param video_time Timestamp value, type defined by `time_mode`. /// \param time_mode How to interpret `video_time`. - VideoTimestamp(int64_t video_time, rerun::datatypes::VideoTimeMode time_mode) - : VideoTimestamp(rerun::datatypes::VideoTimestamp{video_time, time_mode}) {} + VideoTimestamp(int64_t video_time, rerun::datatypes::VideoTimeMode time_mode) { + timestamp.video_time = video_time; + timestamp.time_mode = time_mode; + } /// Creates a new `VideoTimestamp` from time since video start. /// \param time Time since video start. diff --git a/rerun_cpp/src/rerun/components/video_timestamp_ext.cpp b/rerun_cpp/src/rerun/components/video_timestamp_ext.cpp index d00165c231b0..b05e85d54179 100644 --- a/rerun_cpp/src/rerun/components/video_timestamp_ext.cpp +++ b/rerun_cpp/src/rerun/components/video_timestamp_ext.cpp @@ -15,8 +15,10 @@ namespace rerun { /// Creates a new `VideoTimestamp` component. /// \param video_time Timestamp value, type defined by `time_mode`. /// \param time_mode How to interpret `video_time`. - VideoTimestamp(int64_t video_time, rerun::datatypes::VideoTimeMode time_mode) - : VideoTimestamp(rerun::datatypes::VideoTimestamp{video_time, time_mode}) {} + VideoTimestamp(int64_t video_time, rerun::datatypes::VideoTimeMode time_mode) { + timestamp.video_time = video_time; + timestamp.time_mode = time_mode; + } /// Creates a new `VideoTimestamp` from time since video start. /// \param time Time since video start. From e9f52b87c8e78be367ed3283b4fecc671f55a4ef Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Thu, 12 Sep 2024 13:13:02 +0200 Subject: [PATCH 5/6] execute test asset download as part of snippet build --- .../re_dev_tools/src/build_examples/snippets.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/crates/build/re_dev_tools/src/build_examples/snippets.rs b/crates/build/re_dev_tools/src/build_examples/snippets.rs index 7454c556b41c..6b8c8dd9da2f 100644 --- a/crates/build/re_dev_tools/src/build_examples/snippets.rs +++ b/crates/build/re_dev_tools/src/build_examples/snippets.rs @@ -36,8 +36,11 @@ impl Snippets { let snippet_root = snippets_dir.join("all"); let snippets = collect_snippets_recursively(&snippet_root, &config, &snippet_root)?; - println!("Running {} snippets…", snippets.len()); + println!("Download test assets…"); let progress = MultiProgress::new(); + download_test_assets(&progress)?; + + println!("Running {} snippets…", snippets.len()); let results: Vec> = snippets .into_par_iter() .map(|example| example.build(&progress, &self.output_dir)) @@ -190,3 +193,12 @@ struct OptOut { /// example name -> languages run: HashMap>, } + +fn download_test_assets(progress: &MultiProgress) -> anyhow::Result<()> { + let download_script = re_build_tools::cargo_metadata()? + .workspace_root + .join("tests/assets/download_test_assets.py"); + let mut cmd = Command::new("python3"); + cmd.arg(download_script.as_str()); + wait_for_output(cmd, "download test assets", progress) +} From 0140f006e004d00c936041d7ac10100dd6c71670 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Fri, 13 Sep 2024 16:37:41 +0200 Subject: [PATCH 6/6] fix typos --- rerun_cpp/src/rerun/components/video_timestamp.hpp | 1 - rerun_cpp/src/rerun/components/video_timestamp_ext.cpp | 1 - rerun_py/rerun_sdk/rerun/components/video_timestamp_ext.py | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/rerun_cpp/src/rerun/components/video_timestamp.hpp b/rerun_cpp/src/rerun/components/video_timestamp.hpp index 00d6a5aaacc6..ae5e840b13be 100644 --- a/rerun_cpp/src/rerun/components/video_timestamp.hpp +++ b/rerun_cpp/src/rerun/components/video_timestamp.hpp @@ -27,7 +27,6 @@ namespace rerun::components { } /// Creates a new `VideoTimestamp` from time since video start. - /// \param time Time since video start. template VideoTimestamp(std::chrono::duration time) : VideoTimestamp( diff --git a/rerun_cpp/src/rerun/components/video_timestamp_ext.cpp b/rerun_cpp/src/rerun/components/video_timestamp_ext.cpp index b05e85d54179..97d5e61521fd 100644 --- a/rerun_cpp/src/rerun/components/video_timestamp_ext.cpp +++ b/rerun_cpp/src/rerun/components/video_timestamp_ext.cpp @@ -21,7 +21,6 @@ namespace rerun { } /// Creates a new `VideoTimestamp` from time since video start. - /// \param time Time since video start. template VideoTimestamp(std::chrono::duration time) : VideoTimestamp( diff --git a/rerun_py/rerun_sdk/rerun/components/video_timestamp_ext.py b/rerun_py/rerun_sdk/rerun/components/video_timestamp_ext.py index fbee654c9c07..98403aa558cc 100644 --- a/rerun_py/rerun_sdk/rerun/components/video_timestamp_ext.py +++ b/rerun_py/rerun_sdk/rerun/components/video_timestamp_ext.py @@ -54,7 +54,7 @@ def nanoseconds( Parameters ---------- nanoseconds: - Timestamp values in milliseconds since video start. + Timestamp values in nanoseconds since video start. """ nanoseconds = np.asarray(nanoseconds, dtype=np.int64)