diff --git a/docs/source/using_dataset_tools.mdx b/docs/source/using_dataset_tools.mdx index 56334250f..e9299d298 100644 --- a/docs/source/using_dataset_tools.mdx +++ b/docs/source/using_dataset_tools.mdx @@ -181,8 +181,8 @@ lerobot-edit-dataset \ lerobot-edit-dataset \ --repo_id lerobot/pusht_depth \ --operation.type reencode_videos \ - --operation.rgb_encoder.vcodec libx264 \ - --operation.depth_encoder.vcodec ffv1 + --operation.rgb_encoder.vcodec h264 \ + --operation.depth_encoder.crf 50 ``` **Parameters:** diff --git a/docs/source/video_encoding_parameters.mdx b/docs/source/video_encoding_parameters.mdx index 9f52b4541..72ed10458 100644 --- a/docs/source/video_encoding_parameters.mdx +++ b/docs/source/video_encoding_parameters.mdx @@ -102,7 +102,7 @@ lerobot-record \ | Parameter | Type | Default | Description | | ----------- | ------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------- | -| `vcodec` | `str` | `"hevc"` | Defaults to HEVC Main 12 (a 12-bit-capable codec). `ffv1` is a lossless alternative. | +| `vcodec` | `str` | `"hevc"` | Defaults to HEVC Main 12 (a 12-bit-capable codec). For a lossless depth stream, keep HEVC and pass `extra_options={"x265-params": "lossless=1"}` (stays MP4-compatible). | | `pix_fmt` | `str` | `"gray12le"` | Single-channel 12-bit pixel format used to carry the quantized codes. | | `depth_min` | `float` | `0.01` | Depth in metres mapped to quantum `0`. Values below are clipped on decode. | | `depth_max` | `float` | `10.0` | Depth in metres mapped to quantum `4095`. Values above are clipped on decode. | diff --git a/src/lerobot/configs/video.py b/src/lerobot/configs/video.py index c393ad036..1929b638a 100644 --- a/src/lerobot/configs/video.py +++ b/src/lerobot/configs/video.py @@ -37,7 +37,7 @@ HW_VIDEO_CODECS = [ "h264_qsv", # Intel Quick Sync ] VALID_VIDEO_CODECS: frozenset[str] = frozenset( - {"h264", "hevc", "libsvtav1", "ffv1", "auto", *HW_VIDEO_CODECS} + {"h264", "hevc", "libsvtav1", "auto", *HW_VIDEO_CODECS} ) # Aliases for legacy video codec names. VIDEO_CODECS_ALIASES: dict[str, str] = {"av1": "libsvtav1"} @@ -234,10 +234,6 @@ class VideoEncoderConfig: elif self.vcodec == "h264_qsv": set_if("global_quality", self.crf) set_if("preset", self.preset) - elif self.vcodec == "ffv1": - # Lossless intra-frame codec. ``crf``/``preset``/``fast_decode`` - # are not meaningful. - set_if("threads", encoder_threads) else: set_if("crf", self.crf) set_if("preset", self.preset) diff --git a/src/lerobot/datasets/depth_utils.py b/src/lerobot/datasets/depth_utils.py index 8305a94d3..801c86a09 100644 --- a/src/lerobot/datasets/depth_utils.py +++ b/src/lerobot/datasets/depth_utils.py @@ -79,7 +79,7 @@ def quantize_depth( Depth maps are packed into 12-bit integer frames so they fit in standard high-bit-depth pixel formats (e.g. ``yuv420p12le`` / ``gray12le``) - and can be encoded by widely supported video codecs (HEVC Main 12, ffv1). + and can be encoded by widely supported video codecs (e.g. HEVC Main 12). Logarithmic quantization is the default because it allocates more quanta to near-range depth, which matches the (1/depth) error profile of typical depth sensors. Math is ported from BEHAVIOR-1K's ``obs_utils.py``. diff --git a/src/lerobot/scripts/lerobot_edit_dataset.py b/src/lerobot/scripts/lerobot_edit_dataset.py index f7304f5e9..42dce438f 100644 --- a/src/lerobot/scripts/lerobot_edit_dataset.py +++ b/src/lerobot/scripts/lerobot_edit_dataset.py @@ -224,8 +224,8 @@ Re-encode both RGB and depth videos in a dataset (depth quantization params are lerobot-edit-dataset \ --repo_id lerobot/pusht_depth \ --operation.type reencode_videos \ - --operation.rgb_encoder.vcodec libx264 \ - --operation.depth_encoder.vcodec ffv1 + --operation.rgb_encoder.vcodec h264 \ + --operation.depth_encoder.extra_options '{"x265-params": "lossless=1"}' Using JSON config file: lerobot-edit-dataset \ diff --git a/tests/datasets/test_datasets.py b/tests/datasets/test_datasets.py index 21baf4d06..225479814 100644 --- a/tests/datasets/test_datasets.py +++ b/tests/datasets/test_datasets.py @@ -1531,7 +1531,6 @@ def test_valid_video_codecs_constant(): assert "h264" in VALID_VIDEO_CODECS assert "hevc" in VALID_VIDEO_CODECS assert "libsvtav1" in VALID_VIDEO_CODECS - assert "ffv1" in VALID_VIDEO_CODECS assert "auto" in VALID_VIDEO_CODECS assert "h264_videotoolbox" in VALID_VIDEO_CODECS assert "h264_nvenc" in VALID_VIDEO_CODECS @@ -1539,7 +1538,7 @@ def test_valid_video_codecs_constant(): assert "h264_qsv" in VALID_VIDEO_CODECS assert "hevc_videotoolbox" in VALID_VIDEO_CODECS assert "hevc_nvenc" in VALID_VIDEO_CODECS - assert len(VALID_VIDEO_CODECS) == 11 + assert len(VALID_VIDEO_CODECS) == 10 def test_delta_timestamps_with_episodes_filter(tmp_path, empty_lerobot_dataset_factory): diff --git a/tests/scripts/test_edit_dataset_parsing.py b/tests/scripts/test_edit_dataset_parsing.py index 4dfad81f9..22a3c1be2 100644 --- a/tests/scripts/test_edit_dataset_parsing.py +++ b/tests/scripts/test_edit_dataset_parsing.py @@ -123,15 +123,15 @@ class TestDepthEncoderParsing: "test/repo", "--operation.type", "reencode_videos", - "--operation.depth_encoder.vcodec", - "ffv1", + "--operation.depth_encoder.extra_options", + '{"x265-params": "lossless=1"}', "--operation.depth_encoder.depth_max", "12.0", "--operation.depth_encoder.use_log", "false", ] ) - assert cfg.operation.depth_encoder.vcodec == "ffv1" + assert cfg.operation.depth_encoder.extra_options == {"x265-params": "lossless=1"} assert cfg.operation.depth_encoder.depth_max == 12.0 assert cfg.operation.depth_encoder.use_log is False