Skip to content

Commit c23e81e

Browse files
authored
Allow passing seconds/nanoseconds to VideoFrameReference archetype (#7833)
### What * Fixes #7822 Also, passing a float directly will trigger a warning now. ### Checklist * [x] I have read and agree to [Contributor Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and the [Code of Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md) * [x] I've included a screenshot or gif (if applicable) * [x] I have tested the web demo (if applicable): * Using examples from latest `main` build: [rerun.io/viewer](https://rerun.io/viewer/pr/7833?manifest_url=https://app.rerun.io/version/main/examples_manifest.json) * Using full set of examples from `nightly` build: [rerun.io/viewer](https://rerun.io/viewer/pr/7833?manifest_url=https://app.rerun.io/version/nightly/examples_manifest.json) * [x] The PR title and labels are set such as to maximize their usefulness for the next release's CHANGELOG * [x] If applicable, add a new check to the [release checklist](https://github.com/rerun-io/rerun/blob/main/tests/python/release_checklist)! * [x] If have noted any breaking changes to the log API in `CHANGELOG.md` and the migration guide - [PR Build Summary](https://build.rerun.io/pr/7833) - [Recent benchmark results](https://build.rerun.io/graphs/crates.html) - [Wasm size tracking](https://build.rerun.io/graphs/sizes.html) To run all checks from `main`, comment on the PR with `@rerun-bot full-check`.
1 parent 1c02564 commit c23e81e

File tree

6 files changed

+114
-60
lines changed

6 files changed

+114
-60
lines changed

docs/snippets/all/archetypes/video_manual_frames.py

+2-8
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,11 @@
1919
# Create two entities, showing the same video frozen at different times.
2020
rr.log(
2121
"frame_1s",
22-
rr.VideoFrameReference(
23-
timestamp=rr.components.VideoTimestamp(seconds=1.0),
24-
video_reference="video_asset",
25-
),
22+
rr.VideoFrameReference(seconds=1.0, video_reference="video_asset"),
2623
)
2724
rr.log(
2825
"frame_2s",
29-
rr.VideoFrameReference(
30-
timestamp=rr.components.VideoTimestamp(seconds=2.0),
31-
video_reference="video_asset",
32-
),
26+
rr.VideoFrameReference(seconds=2.0, video_reference="video_asset"),
3327
)
3428

3529
# Send blueprint that shows two 2D views next to each other.

rerun_py/rerun_sdk/rerun/archetypes/asset_video.py

+2-8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rerun_py/rerun_sdk/rerun/archetypes/video_frame_reference.py

+6-44
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
from __future__ import annotations
2+
3+
from typing import Any
4+
5+
from .. import components, datatypes
6+
from ..error_utils import _send_warning_or_raise, catch_and_log_exceptions
7+
8+
9+
class VideoFrameReferenceExt:
10+
"""Extension for [VideoFrameReference][rerun.archetypes.VideoFrameReference]."""
11+
12+
def __init__(
13+
self: Any,
14+
timestamp: datatypes.VideoTimestampLike | None = None,
15+
*,
16+
seconds: float | None = None,
17+
nanoseconds: int | None = None,
18+
video_reference: datatypes.EntityPathLike | None = None,
19+
) -> None:
20+
"""
21+
Create a new instance of the VideoFrameReference archetype.
22+
23+
Parameters
24+
----------
25+
timestamp:
26+
References the closest video frame to this timestamp.
27+
28+
Note that this uses the closest video frame instead of the latest at this timestamp
29+
in order to be more forgiving of rounding errors for inprecise timestamp types.
30+
31+
Mutally exclusive with `seconds` and `nanoseconds`.
32+
seconds:
33+
Sets the timestamp to the given number of seconds.
34+
35+
Mutally exclusive with `timestamp` and `nanoseconds`.
36+
nanoseconds:
37+
Sets the timestamp to the given number of nanoseconds.
38+
39+
Mutally exclusive with `timestamp` and `seconds`.
40+
video_reference:
41+
Optional reference to an entity with a [`archetypes.AssetVideo`][rerun.archetypes.AssetVideo].
42+
43+
If none is specified, the video is assumed to be at the same entity.
44+
Note that blueprint overrides on the referenced video will be ignored regardless,
45+
as this is always interpreted as a reference to the data store.
46+
47+
For a series of video frame references, it is recommended to specify this path only once
48+
at the beginning of the series and then rely on latest-at query semantics to
49+
keep the video reference active.
50+
51+
"""
52+
53+
with catch_and_log_exceptions(context=self.__class__.__name__):
54+
if timestamp is None:
55+
if seconds is None and nanoseconds is None:
56+
raise ValueError("Either timestamp or seconds/nanoseconds must be specified.")
57+
timestamp = components.VideoTimestamp(seconds=seconds, nanoseconds=nanoseconds)
58+
elif seconds is not None or nanoseconds is not None:
59+
raise ValueError("Cannot specify both `timestamp` and `seconds`/`nanoseconds`.")
60+
elif isinstance(timestamp, float):
61+
_send_warning_or_raise("Timestamp can't be specified as a float, use `seconds` instead.")
62+
63+
self.__attrs_init__(
64+
timestamp=timestamp,
65+
video_reference=video_reference,
66+
)
67+
return
68+
69+
self.__attrs_clear__()

rerun_py/rerun_sdk/rerun/components/video_timestamp_ext.py

+2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ def __init__(
3838
if nanoseconds is not None:
3939
raise ValueError("Cannot specify both `seconds` and `nanoseconds`.")
4040
nanoseconds = int(seconds * 1e9 + 0.5)
41+
elif nanoseconds is None:
42+
raise ValueError("Either `seconds` or `nanoseconds` must be specified.")
4143

4244
self.__attrs_init__(timestamp_ns=nanoseconds)
4345
return
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from __future__ import annotations
2+
3+
import pytest
4+
import rerun as rr
5+
6+
7+
def test_video_frame_reference() -> None:
8+
rr.set_strict_mode(True)
9+
10+
# Too many args:
11+
with pytest.raises(ValueError):
12+
rr.VideoFrameReference(timestamp=rr.components.VideoTimestamp(seconds=12.3), seconds=12.3, nanoseconds=123)
13+
with pytest.raises(ValueError):
14+
rr.VideoFrameReference(seconds=12.3, nanoseconds=123)
15+
with pytest.raises(ValueError):
16+
rr.VideoFrameReference(timestamp=rr.components.VideoTimestamp(seconds=12.3), nanoseconds=123)
17+
with pytest.raises(ValueError):
18+
rr.VideoFrameReference(seconds=12.3, nanoseconds=123)
19+
20+
# No args:
21+
with pytest.raises(ValueError):
22+
rr.VideoFrameReference()
23+
24+
# Correct usages:
25+
assert rr.VideoFrameReference(seconds=12.3).timestamp == rr.components.VideoTimestampBatch(
26+
rr.components.VideoTimestamp(seconds=12.3)
27+
)
28+
assert rr.VideoFrameReference(nanoseconds=123).timestamp == rr.components.VideoTimestampBatch(
29+
rr.components.VideoTimestamp(nanoseconds=123)
30+
)
31+
assert rr.VideoFrameReference(
32+
timestamp=rr.components.VideoTimestamp(nanoseconds=123)
33+
).timestamp == rr.components.VideoTimestampBatch(rr.components.VideoTimestamp(nanoseconds=123))

0 commit comments

Comments
 (0)