mirror of
https://github.com/huggingface/lerobot.git
synced 2026-07-23 09:46:00 +00:00
chore(renaming): fixing missed RGBEncoderConfig renamings
This commit is contained in:
@@ -39,6 +39,7 @@ from tqdm import tqdm
|
|||||||
|
|
||||||
from lerobot.configs import (
|
from lerobot.configs import (
|
||||||
DepthEncoderConfig,
|
DepthEncoderConfig,
|
||||||
|
RGBEncoderConfig,
|
||||||
VideoEncoderConfig,
|
VideoEncoderConfig,
|
||||||
depth_encoder_defaults,
|
depth_encoder_defaults,
|
||||||
encoder_config_from_video_info,
|
encoder_config_from_video_info,
|
||||||
@@ -1671,7 +1672,7 @@ def convert_image_to_video_dataset(
|
|||||||
dataset: LeRobotDataset,
|
dataset: LeRobotDataset,
|
||||||
output_dir: Path | None = None,
|
output_dir: Path | None = None,
|
||||||
repo_id: str | None = None,
|
repo_id: str | None = None,
|
||||||
rgb_encoder: VideoEncoderConfig | None = None,
|
rgb_encoder: RGBEncoderConfig | None = None,
|
||||||
depth_encoder: DepthEncoderConfig | None = None,
|
depth_encoder: DepthEncoderConfig | None = None,
|
||||||
episode_indices: list[int] | None = None,
|
episode_indices: list[int] | None = None,
|
||||||
num_workers: int = 4,
|
num_workers: int = 4,
|
||||||
@@ -1931,7 +1932,7 @@ def _reencode_video_worker(args: tuple) -> Path:
|
|||||||
|
|
||||||
def reencode_dataset(
|
def reencode_dataset(
|
||||||
dataset: LeRobotDataset,
|
dataset: LeRobotDataset,
|
||||||
rgb_encoder: VideoEncoderConfig | None = None,
|
rgb_encoder: RGBEncoderConfig | None = None,
|
||||||
depth_encoder: DepthEncoderConfig | None = None,
|
depth_encoder: DepthEncoderConfig | None = None,
|
||||||
encoder_threads: int | None = None,
|
encoder_threads: int | None = None,
|
||||||
num_workers: int | None = None,
|
num_workers: int | None = None,
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import torch
|
|||||||
|
|
||||||
from lerobot.configs import (
|
from lerobot.configs import (
|
||||||
DepthEncoderConfig,
|
DepthEncoderConfig,
|
||||||
|
RGBEncoderConfig,
|
||||||
VideoEncoderConfig,
|
VideoEncoderConfig,
|
||||||
depth_encoder_defaults,
|
depth_encoder_defaults,
|
||||||
rgb_encoder_defaults,
|
rgb_encoder_defaults,
|
||||||
@@ -107,7 +108,7 @@ class DatasetWriter:
|
|||||||
self,
|
self,
|
||||||
meta: LeRobotDatasetMetadata,
|
meta: LeRobotDatasetMetadata,
|
||||||
root: Path,
|
root: Path,
|
||||||
rgb_encoder: VideoEncoderConfig | None,
|
rgb_encoder: RGBEncoderConfig | None,
|
||||||
depth_encoder: DepthEncoderConfig | None,
|
depth_encoder: DepthEncoderConfig | None,
|
||||||
encoder_threads: int | None,
|
encoder_threads: int | None,
|
||||||
batch_encoding_size: int,
|
batch_encoding_size: int,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
"""
|
"""
|
||||||
Depth encoding/decoding helpers for :class:`VideoEncoderConfig`.
|
Depth encoding/decoding helpers for :class:`DepthEncoderConfig`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import math
|
import math
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import torch.utils
|
|||||||
from huggingface_hub import HfApi, snapshot_download
|
from huggingface_hub import HfApi, snapshot_download
|
||||||
from huggingface_hub.errors import RevisionNotFoundError
|
from huggingface_hub.errors import RevisionNotFoundError
|
||||||
|
|
||||||
from lerobot.configs import DEFAULT_DEPTH_UNIT, DepthEncoderConfig, VideoEncoderConfig
|
from lerobot.configs import DEFAULT_DEPTH_UNIT, DepthEncoderConfig, RGBEncoderConfig
|
||||||
from lerobot.utils.constants import HF_LEROBOT_HUB_CACHE
|
from lerobot.utils.constants import HF_LEROBOT_HUB_CACHE
|
||||||
|
|
||||||
from .dataset_metadata import CODEBASE_VERSION, LeRobotDatasetMetadata
|
from .dataset_metadata import CODEBASE_VERSION, LeRobotDatasetMetadata
|
||||||
@@ -60,7 +60,7 @@ class LeRobotDataset(torch.utils.data.Dataset):
|
|||||||
return_uint8: bool = False,
|
return_uint8: bool = False,
|
||||||
depth_output_unit: str = DEFAULT_DEPTH_UNIT,
|
depth_output_unit: str = DEFAULT_DEPTH_UNIT,
|
||||||
batch_encoding_size: int = 1,
|
batch_encoding_size: int = 1,
|
||||||
rgb_encoder: VideoEncoderConfig | None = None,
|
rgb_encoder: RGBEncoderConfig | None = None,
|
||||||
depth_encoder: DepthEncoderConfig | None = None,
|
depth_encoder: DepthEncoderConfig | None = None,
|
||||||
encoder_threads: int | None = None,
|
encoder_threads: int | None = None,
|
||||||
streaming_encoding: bool = False,
|
streaming_encoding: bool = False,
|
||||||
@@ -185,7 +185,7 @@ class LeRobotDataset(torch.utils.data.Dataset):
|
|||||||
You can also use the 'pyav' decoder used by Torchvision, which used to be the default option, or 'video_reader' which is another decoder of Torchvision.
|
You can also use the 'pyav' decoder used by Torchvision, which used to be the default option, or 'video_reader' which is another decoder of Torchvision.
|
||||||
batch_encoding_size (int, optional): Number of episodes to accumulate before batch encoding videos.
|
batch_encoding_size (int, optional): Number of episodes to accumulate before batch encoding videos.
|
||||||
Set to 1 for immediate encoding (default), or higher for batched encoding. Defaults to 1.
|
Set to 1 for immediate encoding (default), or higher for batched encoding. Defaults to 1.
|
||||||
rgb_encoder (VideoEncoderConfig | None, optional): Video encoder settings for cameras
|
rgb_encoder (RGBEncoderConfig | None, optional): Video encoder settings for cameras
|
||||||
(codec, quality, etc.). When ``None``, :func:`~lerobot.configs.video.rgb_encoder_defaults`
|
(codec, quality, etc.). When ``None``, :func:`~lerobot.configs.video.rgb_encoder_defaults`
|
||||||
is used by the writer.
|
is used by the writer.
|
||||||
depth_encoder (DepthEncoderConfig | None, optional): Video encoder settings for depth cameras
|
depth_encoder (DepthEncoderConfig | None, optional): Video encoder settings for depth cameras
|
||||||
@@ -330,7 +330,7 @@ class LeRobotDataset(torch.utils.data.Dataset):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def _build_streaming_encoder(
|
def _build_streaming_encoder(
|
||||||
fps: int,
|
fps: int,
|
||||||
rgb_encoder: VideoEncoderConfig | None,
|
rgb_encoder: RGBEncoderConfig | None,
|
||||||
depth_encoder: DepthEncoderConfig | None,
|
depth_encoder: DepthEncoderConfig | None,
|
||||||
encoder_queue_maxsize: int,
|
encoder_queue_maxsize: int,
|
||||||
encoder_threads: int | None,
|
encoder_threads: int | None,
|
||||||
@@ -655,7 +655,7 @@ class LeRobotDataset(torch.utils.data.Dataset):
|
|||||||
image_writer_threads: int = 0,
|
image_writer_threads: int = 0,
|
||||||
video_backend: str | None = None,
|
video_backend: str | None = None,
|
||||||
batch_encoding_size: int = 1,
|
batch_encoding_size: int = 1,
|
||||||
rgb_encoder: VideoEncoderConfig | None = None,
|
rgb_encoder: RGBEncoderConfig | None = None,
|
||||||
depth_encoder: DepthEncoderConfig | None = None,
|
depth_encoder: DepthEncoderConfig | None = None,
|
||||||
metadata_buffer_size: int = 10,
|
metadata_buffer_size: int = 10,
|
||||||
streaming_encoding: bool = False,
|
streaming_encoding: bool = False,
|
||||||
@@ -764,7 +764,7 @@ class LeRobotDataset(torch.utils.data.Dataset):
|
|||||||
force_cache_sync: bool = False,
|
force_cache_sync: bool = False,
|
||||||
video_backend: str | None = None,
|
video_backend: str | None = None,
|
||||||
batch_encoding_size: int = 1,
|
batch_encoding_size: int = 1,
|
||||||
rgb_encoder: VideoEncoderConfig | None = None,
|
rgb_encoder: RGBEncoderConfig | None = None,
|
||||||
depth_encoder: DepthEncoderConfig | None = None,
|
depth_encoder: DepthEncoderConfig | None = None,
|
||||||
encoder_threads: int | None = None,
|
encoder_threads: int | None = None,
|
||||||
image_writer_processes: int = 0,
|
image_writer_processes: int = 0,
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ from PIL import Image
|
|||||||
|
|
||||||
from lerobot.configs import (
|
from lerobot.configs import (
|
||||||
DepthEncoderConfig,
|
DepthEncoderConfig,
|
||||||
|
RGBEncoderConfig,
|
||||||
VideoEncoderConfig,
|
VideoEncoderConfig,
|
||||||
depth_encoder_defaults,
|
depth_encoder_defaults,
|
||||||
rgb_encoder_defaults,
|
rgb_encoder_defaults,
|
||||||
@@ -892,7 +893,7 @@ class StreamingVideoEncoder:
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
fps: int,
|
fps: int,
|
||||||
rgb_encoder: VideoEncoderConfig | None = None,
|
rgb_encoder: RGBEncoderConfig | None = None,
|
||||||
depth_encoder: DepthEncoderConfig | None = None,
|
depth_encoder: DepthEncoderConfig | None = None,
|
||||||
queue_maxsize: int = 30,
|
queue_maxsize: int = 30,
|
||||||
encoder_threads: int | None = None,
|
encoder_threads: int | None = None,
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ pytest.importorskip("av", reason="av is required (install lerobot[dataset])")
|
|||||||
|
|
||||||
import av # noqa: E402
|
import av # noqa: E402
|
||||||
|
|
||||||
from lerobot.configs import VideoEncoderConfig
|
from lerobot.configs import RGBEncoderConfig
|
||||||
from lerobot.datasets.pyav_utils import get_codec
|
from lerobot.datasets.pyav_utils import get_codec
|
||||||
from lerobot.datasets.video_utils import (
|
from lerobot.datasets.video_utils import (
|
||||||
StreamingVideoEncoder,
|
StreamingVideoEncoder,
|
||||||
@@ -57,7 +57,7 @@ class TestCameraEncoderThread:
|
|||||||
result_queue: queue.Queue = queue.Queue(maxsize=1)
|
result_queue: queue.Queue = queue.Queue(maxsize=1)
|
||||||
stop_event = threading.Event()
|
stop_event = threading.Event()
|
||||||
|
|
||||||
enc_cfg = VideoEncoderConfig(vcodec="libsvtav1", pix_fmt="yuv420p", g=2, crf=30, preset=13)
|
enc_cfg = RGBEncoderConfig(vcodec="libsvtav1", pix_fmt="yuv420p", g=2, crf=30, preset=13)
|
||||||
encoder_thread = _CameraEncoderThread(
|
encoder_thread = _CameraEncoderThread(
|
||||||
video_path=video_path,
|
video_path=video_path,
|
||||||
fps=fps,
|
fps=fps,
|
||||||
@@ -106,7 +106,7 @@ class TestCameraEncoderThread:
|
|||||||
result_queue: queue.Queue = queue.Queue(maxsize=1)
|
result_queue: queue.Queue = queue.Queue(maxsize=1)
|
||||||
stop_event = threading.Event()
|
stop_event = threading.Event()
|
||||||
|
|
||||||
enc_cfg = VideoEncoderConfig(vcodec="libsvtav1", pix_fmt="yuv420p", g=2, crf=30, preset=13)
|
enc_cfg = RGBEncoderConfig(vcodec="libsvtav1", pix_fmt="yuv420p", g=2, crf=30, preset=13)
|
||||||
encoder_thread = _CameraEncoderThread(
|
encoder_thread = _CameraEncoderThread(
|
||||||
video_path=video_path,
|
video_path=video_path,
|
||||||
fps=fps,
|
fps=fps,
|
||||||
@@ -138,7 +138,7 @@ class TestCameraEncoderThread:
|
|||||||
result_queue: queue.Queue = queue.Queue(maxsize=1)
|
result_queue: queue.Queue = queue.Queue(maxsize=1)
|
||||||
stop_event = threading.Event()
|
stop_event = threading.Event()
|
||||||
|
|
||||||
enc_cfg = VideoEncoderConfig(vcodec="libsvtav1", pix_fmt="yuv420p", g=2, crf=30, preset=13)
|
enc_cfg = RGBEncoderConfig(vcodec="libsvtav1", pix_fmt="yuv420p", g=2, crf=30, preset=13)
|
||||||
encoder_thread = _CameraEncoderThread(
|
encoder_thread = _CameraEncoderThread(
|
||||||
video_path=video_path,
|
video_path=video_path,
|
||||||
fps=fps,
|
fps=fps,
|
||||||
@@ -165,8 +165,8 @@ class TestCameraEncoderThread:
|
|||||||
|
|
||||||
class TestStreamingVideoEncoder:
|
class TestStreamingVideoEncoder:
|
||||||
def _make_encoder_config(self, **kwargs):
|
def _make_encoder_config(self, **kwargs):
|
||||||
"""Helper to build a VideoEncoderConfig."""
|
"""Helper to build an RGBEncoderConfig."""
|
||||||
return VideoEncoderConfig(**kwargs)
|
return RGBEncoderConfig(**kwargs)
|
||||||
|
|
||||||
def test_single_camera_episode(self, tmp_path):
|
def test_single_camera_episode(self, tmp_path):
|
||||||
"""Test encoding a single camera episode."""
|
"""Test encoding a single camera episode."""
|
||||||
@@ -369,7 +369,7 @@ class TestStreamingVideoEncoder:
|
|||||||
def test_encoder_threads_passed_to_thread(self, tmp_path):
|
def test_encoder_threads_passed_to_thread(self, tmp_path):
|
||||||
"""Test that encoder_threads is stored and passed through to encoder threads."""
|
"""Test that encoder_threads is stored and passed through to encoder threads."""
|
||||||
video_keys = [f"{OBS_IMAGES}.cam"]
|
video_keys = [f"{OBS_IMAGES}.cam"]
|
||||||
cfg = VideoEncoderConfig(
|
cfg = RGBEncoderConfig(
|
||||||
vcodec="libsvtav1",
|
vcodec="libsvtav1",
|
||||||
pix_fmt="yuv420p",
|
pix_fmt="yuv420p",
|
||||||
g=2,
|
g=2,
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ pytest.importorskip("av", reason="av is required (install lerobot[dataset])")
|
|||||||
|
|
||||||
import av # noqa: E402
|
import av # noqa: E402
|
||||||
|
|
||||||
from lerobot.configs import VALID_VIDEO_CODECS, DepthEncoderConfig, VideoEncoderConfig
|
from lerobot.configs import VALID_VIDEO_CODECS, DepthEncoderConfig, RGBEncoderConfig, VideoEncoderConfig
|
||||||
from lerobot.datasets.image_writer import write_image
|
from lerobot.datasets.image_writer import write_image
|
||||||
from lerobot.datasets.lerobot_dataset import LeRobotDataset
|
from lerobot.datasets.lerobot_dataset import LeRobotDataset
|
||||||
from lerobot.datasets.pyav_utils import get_codec
|
from lerobot.datasets.pyav_utils import get_codec
|
||||||
@@ -117,13 +117,13 @@ def _read_feature_info(dataset: LeRobotDataset, key: str = DUMMY_VIDEO_KEY) -> d
|
|||||||
return info["features"][key]["info"]
|
return info["features"][key]["info"]
|
||||||
|
|
||||||
|
|
||||||
# ─── VideoEncoderConfig / codec options ──────────────────────────────
|
# ─── RGBEncoderConfig / codec options ──────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
class TestCodecOptions:
|
class TestCodecOptions:
|
||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_libsvtav1_defaults(self):
|
def test_libsvtav1_defaults(self):
|
||||||
cfg = VideoEncoderConfig()
|
cfg = RGBEncoderConfig()
|
||||||
opts = cfg.get_codec_options()
|
opts = cfg.get_codec_options()
|
||||||
assert opts["g"] == 2
|
assert opts["g"] == 2
|
||||||
assert opts["crf"] == 30
|
assert opts["crf"] == 30
|
||||||
@@ -131,12 +131,12 @@ class TestCodecOptions:
|
|||||||
|
|
||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_libsvtav1_custom_preset(self):
|
def test_libsvtav1_custom_preset(self):
|
||||||
cfg = VideoEncoderConfig(preset=8)
|
cfg = RGBEncoderConfig(preset=8)
|
||||||
assert cfg.get_codec_options()["preset"] == 8
|
assert cfg.get_codec_options()["preset"] == 8
|
||||||
|
|
||||||
@require_h264
|
@require_h264
|
||||||
def test_h264_options(self):
|
def test_h264_options(self):
|
||||||
cfg = VideoEncoderConfig(vcodec="h264", g=10, crf=23, preset=None)
|
cfg = RGBEncoderConfig(vcodec="h264", g=10, crf=23, preset=None)
|
||||||
opts = cfg.get_codec_options()
|
opts = cfg.get_codec_options()
|
||||||
assert opts["g"] == 10
|
assert opts["g"] == 10
|
||||||
assert opts["crf"] == 23
|
assert opts["crf"] == 23
|
||||||
@@ -144,7 +144,7 @@ class TestCodecOptions:
|
|||||||
|
|
||||||
@require_videotoolbox
|
@require_videotoolbox
|
||||||
def test_videotoolbox_options(self):
|
def test_videotoolbox_options(self):
|
||||||
cfg = VideoEncoderConfig(vcodec="h264_videotoolbox", g=2, crf=30, preset=None)
|
cfg = RGBEncoderConfig(vcodec="h264_videotoolbox", g=2, crf=30, preset=None)
|
||||||
opts = cfg.get_codec_options()
|
opts = cfg.get_codec_options()
|
||||||
assert opts["g"] == 2
|
assert opts["g"] == 2
|
||||||
assert opts["q:v"] == 40
|
assert opts["q:v"] == 40
|
||||||
@@ -152,7 +152,7 @@ class TestCodecOptions:
|
|||||||
|
|
||||||
@require_nvenc
|
@require_nvenc
|
||||||
def test_nvenc_options(self):
|
def test_nvenc_options(self):
|
||||||
cfg = VideoEncoderConfig(vcodec="h264_nvenc", g=2, crf=25, preset=None)
|
cfg = RGBEncoderConfig(vcodec="h264_nvenc", g=2, crf=25, preset=None)
|
||||||
opts = cfg.get_codec_options()
|
opts = cfg.get_codec_options()
|
||||||
assert opts["rc"] == 0
|
assert opts["rc"] == 0
|
||||||
assert opts["qp"] == 25
|
assert opts["qp"] == 25
|
||||||
@@ -161,103 +161,103 @@ class TestCodecOptions:
|
|||||||
|
|
||||||
@require_vaapi
|
@require_vaapi
|
||||||
def test_vaapi_options(self):
|
def test_vaapi_options(self):
|
||||||
cfg = VideoEncoderConfig(vcodec="h264_vaapi", crf=28, preset=None)
|
cfg = RGBEncoderConfig(vcodec="h264_vaapi", crf=28, preset=None)
|
||||||
assert cfg.get_codec_options()["qp"] == 28
|
assert cfg.get_codec_options()["qp"] == 28
|
||||||
|
|
||||||
@require_qsv
|
@require_qsv
|
||||||
def test_qsv_options(self):
|
def test_qsv_options(self):
|
||||||
cfg = VideoEncoderConfig(vcodec="h264_qsv", crf=25, preset=None)
|
cfg = RGBEncoderConfig(vcodec="h264_qsv", crf=25, preset=None)
|
||||||
assert cfg.get_codec_options()["global_quality"] == 25
|
assert cfg.get_codec_options()["global_quality"] == 25
|
||||||
|
|
||||||
@require_h264
|
@require_h264
|
||||||
def test_no_g_no_crf(self):
|
def test_no_g_no_crf(self):
|
||||||
cfg = VideoEncoderConfig(vcodec="h264", g=None, crf=None, preset=None)
|
cfg = RGBEncoderConfig(vcodec="h264", g=None, crf=None, preset=None)
|
||||||
opts = cfg.get_codec_options()
|
opts = cfg.get_codec_options()
|
||||||
assert "g" not in opts
|
assert "g" not in opts
|
||||||
assert "crf" not in opts
|
assert "crf" not in opts
|
||||||
|
|
||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_encoder_threads_libsvtav1(self):
|
def test_encoder_threads_libsvtav1(self):
|
||||||
cfg = VideoEncoderConfig(fast_decode=0)
|
cfg = RGBEncoderConfig(fast_decode=0)
|
||||||
opts = cfg.get_codec_options(encoder_threads=4)
|
opts = cfg.get_codec_options(encoder_threads=4)
|
||||||
assert "lp=4" in opts.get("svtav1-params", "")
|
assert "lp=4" in opts.get("svtav1-params", "")
|
||||||
|
|
||||||
@require_h264
|
@require_h264
|
||||||
def test_encoder_threads_h264(self):
|
def test_encoder_threads_h264(self):
|
||||||
cfg = VideoEncoderConfig(vcodec="h264", preset=None)
|
cfg = RGBEncoderConfig(vcodec="h264", preset=None)
|
||||||
assert cfg.get_codec_options(encoder_threads=2)["threads"] == 2
|
assert cfg.get_codec_options(encoder_threads=2)["threads"] == 2
|
||||||
|
|
||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_fast_decode_libsvtav1(self):
|
def test_fast_decode_libsvtav1(self):
|
||||||
cfg = VideoEncoderConfig(fast_decode=1)
|
cfg = RGBEncoderConfig(fast_decode=1)
|
||||||
opts = cfg.get_codec_options()
|
opts = cfg.get_codec_options()
|
||||||
assert "fast-decode=1" in opts.get("svtav1-params", "")
|
assert "fast-decode=1" in opts.get("svtav1-params", "")
|
||||||
|
|
||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_libsvtav1_fast_decode_clamped_to_svt_range(self):
|
def test_libsvtav1_fast_decode_clamped_to_svt_range(self):
|
||||||
"""Out-of-range fast_decode is clamped to [0, 2] in svtav1-params (SVT-AV1 FastDecode)."""
|
"""Out-of-range fast_decode is clamped to [0, 2] in svtav1-params (SVT-AV1 FastDecode)."""
|
||||||
cfg = VideoEncoderConfig(fast_decode=100)
|
cfg = RGBEncoderConfig(fast_decode=100)
|
||||||
assert "fast-decode=2" in cfg.get_codec_options().get("svtav1-params", "")
|
assert "fast-decode=2" in cfg.get_codec_options().get("svtav1-params", "")
|
||||||
cfg_neg = VideoEncoderConfig(fast_decode=-5)
|
cfg_neg = RGBEncoderConfig(fast_decode=-5)
|
||||||
assert "fast-decode=0" in cfg_neg.get_codec_options().get("svtav1-params", "")
|
assert "fast-decode=0" in cfg_neg.get_codec_options().get("svtav1-params", "")
|
||||||
|
|
||||||
@require_h264
|
@require_h264
|
||||||
def test_fast_decode_h264(self):
|
def test_fast_decode_h264(self):
|
||||||
cfg = VideoEncoderConfig(vcodec="h264", fast_decode=1, preset=None)
|
cfg = RGBEncoderConfig(vcodec="h264", fast_decode=1, preset=None)
|
||||||
assert cfg.get_codec_options()["tune"] == "fastdecode"
|
assert cfg.get_codec_options()["tune"] == "fastdecode"
|
||||||
|
|
||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_pix_fmt_unsupported_raises(self):
|
def test_pix_fmt_unsupported_raises(self):
|
||||||
"""Passing an unsupported pix_fmt is a hard error."""
|
"""Passing an unsupported pix_fmt is a hard error."""
|
||||||
with pytest.raises(ValueError, match="pix_fmt"):
|
with pytest.raises(ValueError, match="pix_fmt"):
|
||||||
VideoEncoderConfig(pix_fmt="yuv444p") # libsvtav1 only supports yuv420p variants
|
RGBEncoderConfig(pix_fmt="yuv444p") # libsvtav1 only supports yuv420p variants
|
||||||
|
|
||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
@require_h264
|
@require_h264
|
||||||
def test_preset_default_behaviour(self):
|
def test_preset_default_behaviour(self):
|
||||||
"""Empty constructor picks preset=12 (libsvtav1 path); other codecs stay None."""
|
"""Empty constructor picks preset=12 (libsvtav1 path); other codecs stay None."""
|
||||||
assert VideoEncoderConfig().preset == 12
|
assert RGBEncoderConfig().preset == 12
|
||||||
assert VideoEncoderConfig(vcodec="libsvtav1").preset == 12
|
assert RGBEncoderConfig(vcodec="libsvtav1").preset == 12
|
||||||
assert VideoEncoderConfig(vcodec="h264").preset is None
|
assert RGBEncoderConfig(vcodec="h264").preset is None
|
||||||
assert VideoEncoderConfig(vcodec="h264", preset=None).preset is None
|
assert RGBEncoderConfig(vcodec="h264", preset=None).preset is None
|
||||||
|
|
||||||
@require_h264
|
@require_h264
|
||||||
def test_preset_string_on_h264(self):
|
def test_preset_string_on_h264(self):
|
||||||
"""h264 accepts string presets and forwards them to FFmpeg."""
|
"""h264 accepts string presets and forwards them to FFmpeg."""
|
||||||
cfg = VideoEncoderConfig(vcodec="h264", preset="slow")
|
cfg = RGBEncoderConfig(vcodec="h264", preset="slow")
|
||||||
assert cfg.get_codec_options()["preset"] == "slow"
|
assert cfg.get_codec_options()["preset"] == "slow"
|
||||||
|
|
||||||
@require_videotoolbox
|
@require_videotoolbox
|
||||||
def test_preset_on_videotoolbox_not_set(self):
|
def test_preset_on_videotoolbox_not_set(self):
|
||||||
"""videotoolbox has no preset option at all."""
|
"""videotoolbox has no preset option at all."""
|
||||||
cfg = VideoEncoderConfig(vcodec="h264_videotoolbox", preset="slow")
|
cfg = RGBEncoderConfig(vcodec="h264_videotoolbox", preset="slow")
|
||||||
assert "preset" not in cfg.get_codec_options()
|
assert "preset" not in cfg.get_codec_options()
|
||||||
|
|
||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_libsvtav1_preset_out_of_range_raises(self):
|
def test_libsvtav1_preset_out_of_range_raises(self):
|
||||||
"""libsvtav1 preset must sit in [-2, 13] as exposed by PyAV."""
|
"""libsvtav1 preset must sit in [-2, 13] as exposed by PyAV."""
|
||||||
with pytest.raises(ValueError, match="out of range"):
|
with pytest.raises(ValueError, match="out of range"):
|
||||||
VideoEncoderConfig(vcodec="libsvtav1", preset=100)
|
RGBEncoderConfig(vcodec="libsvtav1", preset=100)
|
||||||
with pytest.raises(ValueError, match="out of range"):
|
with pytest.raises(ValueError, match="out of range"):
|
||||||
VideoEncoderConfig(vcodec="libsvtav1", preset=-3)
|
RGBEncoderConfig(vcodec="libsvtav1", preset=-3)
|
||||||
|
|
||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_libsvtav1_crf_out_of_range_raises(self):
|
def test_libsvtav1_crf_out_of_range_raises(self):
|
||||||
"""libsvtav1 crf must sit in [0, 63]."""
|
"""libsvtav1 crf must sit in [0, 63]."""
|
||||||
with pytest.raises(ValueError, match="crf.*out of range"):
|
with pytest.raises(ValueError, match="crf.*out of range"):
|
||||||
VideoEncoderConfig(vcodec="libsvtav1", crf=64)
|
RGBEncoderConfig(vcodec="libsvtav1", crf=64)
|
||||||
|
|
||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_libsvtav1_crf_rejects_python_float(self):
|
def test_libsvtav1_crf_rejects_python_float(self):
|
||||||
"""libsvtav1 exposes ``crf`` as an INT AVOption; Python float must not pass validation."""
|
"""libsvtav1 exposes ``crf`` as an INT AVOption; Python float must not pass validation."""
|
||||||
with pytest.raises(ValueError, match="float values are not allowed"):
|
with pytest.raises(ValueError, match="float values are not allowed"):
|
||||||
VideoEncoderConfig(vcodec="libsvtav1", crf=2.5)
|
RGBEncoderConfig(vcodec="libsvtav1", crf=2.5)
|
||||||
|
|
||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_libsvtav1_extra_crf_rejects_fractional_string(self):
|
def test_libsvtav1_extra_crf_rejects_fractional_string(self):
|
||||||
"""INT options reject fractional values even when supplied only via ``extra_options``."""
|
"""INT options reject fractional values even when supplied only via ``extra_options``."""
|
||||||
with pytest.raises(ValueError, match="float values are not allowed"):
|
with pytest.raises(ValueError, match="float values are not allowed"):
|
||||||
VideoEncoderConfig(
|
RGBEncoderConfig(
|
||||||
vcodec="libsvtav1",
|
vcodec="libsvtav1",
|
||||||
crf=None,
|
crf=None,
|
||||||
extra_options={"crf": "2.5"},
|
extra_options={"crf": "2.5"},
|
||||||
@@ -266,7 +266,7 @@ class TestCodecOptions:
|
|||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_libsvtav1_extra_crf_rejects_float(self):
|
def test_libsvtav1_extra_crf_rejects_float(self):
|
||||||
with pytest.raises(ValueError, match="float values are not allowed"):
|
with pytest.raises(ValueError, match="float values are not allowed"):
|
||||||
VideoEncoderConfig(
|
RGBEncoderConfig(
|
||||||
vcodec="libsvtav1",
|
vcodec="libsvtav1",
|
||||||
crf=None,
|
crf=None,
|
||||||
extra_options={"crf": 2.5},
|
extra_options={"crf": 2.5},
|
||||||
@@ -275,13 +275,13 @@ class TestCodecOptions:
|
|||||||
@require_h264
|
@require_h264
|
||||||
def test_h264_crf_accepts_float_and_int(self):
|
def test_h264_crf_accepts_float_and_int(self):
|
||||||
"""x264 exposes crf as a FLOAT option, so both int and float are accepted."""
|
"""x264 exposes crf as a FLOAT option, so both int and float are accepted."""
|
||||||
assert VideoEncoderConfig(vcodec="h264", crf=23).get_codec_options()["crf"] == 23
|
assert RGBEncoderConfig(vcodec="h264", crf=23).get_codec_options()["crf"] == 23
|
||||||
assert VideoEncoderConfig(vcodec="h264", crf=23.5).get_codec_options()["crf"] == 23.5
|
assert RGBEncoderConfig(vcodec="h264", crf=23.5).get_codec_options()["crf"] == 23.5
|
||||||
|
|
||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_validate_is_rerunnable(self):
|
def test_validate_is_rerunnable(self):
|
||||||
"""After mutating a field, validate() re-checks and surfaces new issues."""
|
"""After mutating a field, validate() re-checks and surfaces new issues."""
|
||||||
cfg = VideoEncoderConfig(vcodec="libsvtav1")
|
cfg = RGBEncoderConfig(vcodec="libsvtav1")
|
||||||
cfg.preset = 100 # now out of range
|
cfg.preset = 100 # now out of range
|
||||||
with pytest.raises(ValueError, match="out of range"):
|
with pytest.raises(ValueError, match="out of range"):
|
||||||
cfg.validate()
|
cfg.validate()
|
||||||
@@ -290,58 +290,58 @@ class TestCodecOptions:
|
|||||||
class TestExtraOptions:
|
class TestExtraOptions:
|
||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_default_is_empty_dict(self):
|
def test_default_is_empty_dict(self):
|
||||||
cfg = VideoEncoderConfig()
|
cfg = RGBEncoderConfig()
|
||||||
assert cfg.extra_options == {}
|
assert cfg.extra_options == {}
|
||||||
|
|
||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_unknown_key_passes_through(self):
|
def test_unknown_key_passes_through(self):
|
||||||
"""Keys not published as AVOptions are forwarded to FFmpeg."""
|
"""Keys not published as AVOptions are forwarded to FFmpeg."""
|
||||||
cfg = VideoEncoderConfig(extra_options={"totally_made_up_option": "value"})
|
cfg = RGBEncoderConfig(extra_options={"totally_made_up_option": "value"})
|
||||||
assert cfg.extra_options == {"totally_made_up_option": "value"}
|
assert cfg.extra_options == {"totally_made_up_option": "value"}
|
||||||
|
|
||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_numeric_value_in_range_ok(self):
|
def test_numeric_value_in_range_ok(self):
|
||||||
"""libsvtav1 exposes ``qp`` as INT in [0, 63]."""
|
"""libsvtav1 exposes ``qp`` as INT in [0, 63]."""
|
||||||
cfg = VideoEncoderConfig(extra_options={"qp": 30})
|
cfg = RGBEncoderConfig(extra_options={"qp": 30})
|
||||||
assert cfg.extra_options == {"qp": 30}
|
assert cfg.extra_options == {"qp": 30}
|
||||||
|
|
||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_numeric_out_of_range_raises(self):
|
def test_numeric_out_of_range_raises(self):
|
||||||
with pytest.raises(ValueError, match=r"qp=.*out of range"):
|
with pytest.raises(ValueError, match=r"qp=.*out of range"):
|
||||||
VideoEncoderConfig(extra_options={"qp": 999})
|
RGBEncoderConfig(extra_options={"qp": 999})
|
||||||
|
|
||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_numeric_string_accepted_in_range(self):
|
def test_numeric_string_accepted_in_range(self):
|
||||||
"""Numeric strings are accepted for numeric options (mirrors FFmpeg)."""
|
"""Numeric strings are accepted for numeric options (mirrors FFmpeg)."""
|
||||||
cfg = VideoEncoderConfig(extra_options={"qp": "18"})
|
cfg = RGBEncoderConfig(extra_options={"qp": "18"})
|
||||||
assert cfg.extra_options == {"qp": "18"}
|
assert cfg.extra_options == {"qp": "18"}
|
||||||
|
|
||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_numeric_string_out_of_range_raises(self):
|
def test_numeric_string_out_of_range_raises(self):
|
||||||
with pytest.raises(ValueError, match=r"qp=.*out of range"):
|
with pytest.raises(ValueError, match=r"qp=.*out of range"):
|
||||||
VideoEncoderConfig(extra_options={"qp": "999"})
|
RGBEncoderConfig(extra_options={"qp": "999"})
|
||||||
|
|
||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_non_numeric_string_on_numeric_option_raises(self):
|
def test_non_numeric_string_on_numeric_option_raises(self):
|
||||||
with pytest.raises(ValueError, match=r"qp=.*not numeric"):
|
with pytest.raises(ValueError, match=r"qp=.*not numeric"):
|
||||||
VideoEncoderConfig(extra_options={"qp": "medium"})
|
RGBEncoderConfig(extra_options={"qp": "medium"})
|
||||||
|
|
||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_bool_on_numeric_option_raises(self):
|
def test_bool_on_numeric_option_raises(self):
|
||||||
"""``bool`` is explicitly rejected for numeric options."""
|
"""``bool`` is explicitly rejected for numeric options."""
|
||||||
with pytest.raises(ValueError, match=r"qp=.*not numeric"):
|
with pytest.raises(ValueError, match=r"qp=.*not numeric"):
|
||||||
VideoEncoderConfig(extra_options={"qp": True})
|
RGBEncoderConfig(extra_options={"qp": True})
|
||||||
|
|
||||||
@require_h264
|
@require_h264
|
||||||
def test_string_option_passes_through_unchecked(self):
|
def test_string_option_passes_through_unchecked(self):
|
||||||
"""String-typed AVOptions are NOT enum-checked (too many accept freeform)."""
|
"""String-typed AVOptions are NOT enum-checked (too many accept freeform)."""
|
||||||
cfg = VideoEncoderConfig(vcodec="h264", preset=None, extra_options={"tune": "some-future-tune"})
|
cfg = RGBEncoderConfig(vcodec="h264", preset=None, extra_options={"tune": "some-future-tune"})
|
||||||
assert cfg.extra_options == {"tune": "some-future-tune"}
|
assert cfg.extra_options == {"tune": "some-future-tune"}
|
||||||
|
|
||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_merged_into_codec_options_and_stringified(self):
|
def test_merged_into_codec_options_and_stringified(self):
|
||||||
"""Typed merge by default; ``as_strings=True`` matches FFmpeg option dict."""
|
"""Typed merge by default; ``as_strings=True`` matches FFmpeg option dict."""
|
||||||
cfg = VideoEncoderConfig(extra_options={"qp": 20})
|
cfg = RGBEncoderConfig(extra_options={"qp": 20})
|
||||||
opts = cfg.get_codec_options()
|
opts = cfg.get_codec_options()
|
||||||
assert opts["qp"] == 20
|
assert opts["qp"] == 20
|
||||||
assert isinstance(opts["qp"], int)
|
assert isinstance(opts["qp"], int)
|
||||||
@@ -350,25 +350,25 @@ class TestExtraOptions:
|
|||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_structured_fields_win_on_collision(self):
|
def test_structured_fields_win_on_collision(self):
|
||||||
"""A colliding extra_options key is discarded; the structured field wins."""
|
"""A colliding extra_options key is discarded; the structured field wins."""
|
||||||
cfg = VideoEncoderConfig(crf=30, extra_options={"crf": 18})
|
cfg = RGBEncoderConfig(crf=30, extra_options={"crf": 18})
|
||||||
assert cfg.get_codec_options()["crf"] == 30
|
assert cfg.get_codec_options()["crf"] == 30
|
||||||
|
|
||||||
|
|
||||||
class TestEncoderDetection:
|
class TestEncoderDetection:
|
||||||
@require_h264
|
@require_h264
|
||||||
def test_explicit_codec_kept_when_available(self):
|
def test_explicit_codec_kept_when_available(self):
|
||||||
cfg = VideoEncoderConfig(vcodec="h264")
|
cfg = RGBEncoderConfig(vcodec="h264")
|
||||||
assert cfg.vcodec == "h264"
|
assert cfg.vcodec == "h264"
|
||||||
|
|
||||||
@require_videotoolbox
|
@require_videotoolbox
|
||||||
def test_auto_picks_videotoolbox_when_available(self):
|
def test_auto_picks_videotoolbox_when_available(self):
|
||||||
"""``h264_videotoolbox`` sits at the top of ``HW_VIDEO_CODECS`` so it wins when present."""
|
"""``h264_videotoolbox`` sits at the top of ``HW_VIDEO_CODECS`` so it wins when present."""
|
||||||
cfg = VideoEncoderConfig(vcodec="auto")
|
cfg = RGBEncoderConfig(vcodec="auto")
|
||||||
assert cfg.vcodec == "h264_videotoolbox"
|
assert cfg.vcodec == "h264_videotoolbox"
|
||||||
|
|
||||||
def test_invalid_codec_raises(self):
|
def test_invalid_codec_raises(self):
|
||||||
with pytest.raises(ValueError, match="Invalid vcodec"):
|
with pytest.raises(ValueError, match="Invalid vcodec"):
|
||||||
VideoEncoderConfig(vcodec="not_a_real_codec")
|
RGBEncoderConfig(vcodec="not_a_real_codec")
|
||||||
|
|
||||||
def test_hw_encoder_names_listed_as_valid(self):
|
def test_hw_encoder_names_listed_as_valid(self):
|
||||||
assert "auto" in VALID_VIDEO_CODECS
|
assert "auto" in VALID_VIDEO_CODECS
|
||||||
@@ -393,7 +393,7 @@ class TestGetVideoInfo:
|
|||||||
|
|
||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_merges_encoder_config_as_video_prefixed_entries(self):
|
def test_merges_encoder_config_as_video_prefixed_entries(self):
|
||||||
cfg = VideoEncoderConfig(vcodec="libsvtav1", g=2, crf=30, preset=12)
|
cfg = RGBEncoderConfig(vcodec="libsvtav1", g=2, crf=30, preset=12)
|
||||||
|
|
||||||
info = get_video_info(TEST_ARTIFACTS_DIR / "clip_4frames.mp4", video_encoder=cfg)
|
info = get_video_info(TEST_ARTIFACTS_DIR / "clip_4frames.mp4", video_encoder=cfg)
|
||||||
|
|
||||||
@@ -406,7 +406,7 @@ class TestGetVideoInfo:
|
|||||||
|
|
||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_stream_derived_keys_take_precedence_over_config(self):
|
def test_stream_derived_keys_take_precedence_over_config(self):
|
||||||
cfg = VideoEncoderConfig(vcodec="libsvtav1", pix_fmt="yuv420p")
|
cfg = RGBEncoderConfig(vcodec="libsvtav1", pix_fmt="yuv420p")
|
||||||
|
|
||||||
info = get_video_info(TEST_ARTIFACTS_DIR / "clip_4frames.mp4", video_encoder=cfg)
|
info = get_video_info(TEST_ARTIFACTS_DIR / "clip_4frames.mp4", video_encoder=cfg)
|
||||||
|
|
||||||
@@ -473,7 +473,7 @@ class TestEncodeVideoFrames:
|
|||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_custom_encoder_config_fields_stored_in_info(self, tmp_path):
|
def test_custom_encoder_config_fields_stored_in_info(self, tmp_path):
|
||||||
"""All stream-derived and encoder config fields are present after encoding."""
|
"""All stream-derived and encoder config fields are present after encoding."""
|
||||||
cfg = VideoEncoderConfig(vcodec="libsvtav1", g=4, crf=25, preset=10)
|
cfg = RGBEncoderConfig(vcodec="libsvtav1", g=4, crf=25, preset=10)
|
||||||
video_path = _encode_video(tmp_path / "out.mp4", num_frames=4, fps=30, cfg=cfg)
|
video_path = _encode_video(tmp_path / "out.mp4", num_frames=4, fps=30, cfg=cfg)
|
||||||
|
|
||||||
info = get_video_info(video_path, video_encoder=cfg)
|
info = get_video_info(video_path, video_encoder=cfg)
|
||||||
@@ -502,7 +502,7 @@ class TestReencodeVideo:
|
|||||||
def test_reencode_video(self, tmp_path):
|
def test_reencode_video(self, tmp_path):
|
||||||
src = TEST_ARTIFACTS_DIR / "clip_4frames.mp4"
|
src = TEST_ARTIFACTS_DIR / "clip_4frames.mp4"
|
||||||
out = tmp_path / "reencoded.mp4"
|
out = tmp_path / "reencoded.mp4"
|
||||||
cfg = VideoEncoderConfig(vcodec="h264", g=6, crf=23, pix_fmt="yuv444p")
|
cfg = RGBEncoderConfig(vcodec="h264", g=6, crf=23, pix_fmt="yuv444p")
|
||||||
reencode_video(src, out, video_encoder=cfg, overwrite=True)
|
reencode_video(src, out, video_encoder=cfg, overwrite=True)
|
||||||
|
|
||||||
assert out.exists()
|
assert out.exists()
|
||||||
@@ -523,7 +523,7 @@ class TestReencodeVideo:
|
|||||||
def test_reencode_video_trim_window(self, tmp_path):
|
def test_reencode_video_trim_window(self, tmp_path):
|
||||||
src = TEST_ARTIFACTS_DIR / "clip_6frames.mp4"
|
src = TEST_ARTIFACTS_DIR / "clip_6frames.mp4"
|
||||||
out = tmp_path / "trim_window.mp4"
|
out = tmp_path / "trim_window.mp4"
|
||||||
cfg = VideoEncoderConfig(vcodec="h264")
|
cfg = RGBEncoderConfig(vcodec="h264")
|
||||||
reencode_video(src, out, video_encoder=cfg, start_time_s=0.05, end_time_s=0.12, overwrite=True)
|
reencode_video(src, out, video_encoder=cfg, start_time_s=0.05, end_time_s=0.12, overwrite=True)
|
||||||
|
|
||||||
with av.open(str(out)) as container:
|
with av.open(str(out)) as container:
|
||||||
@@ -593,7 +593,7 @@ class TestEncoderConfigPersistence:
|
|||||||
|
|
||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_first_episode_save_persists_encoder_config(self, tmp_path, empty_lerobot_dataset_factory):
|
def test_first_episode_save_persists_encoder_config(self, tmp_path, empty_lerobot_dataset_factory):
|
||||||
cfg = VideoEncoderConfig(vcodec="libsvtav1", g=2, crf=30, preset=12)
|
cfg = RGBEncoderConfig(vcodec="libsvtav1", g=2, crf=30, preset=12)
|
||||||
dataset = empty_lerobot_dataset_factory(
|
dataset = empty_lerobot_dataset_factory(
|
||||||
root=tmp_path / "ds", features=DUMMY_VIDEO_FEATURES, use_videos=True, rgb_encoder=cfg
|
root=tmp_path / "ds", features=DUMMY_VIDEO_FEATURES, use_videos=True, rgb_encoder=cfg
|
||||||
)
|
)
|
||||||
@@ -616,7 +616,7 @@ class TestEncoderConfigPersistence:
|
|||||||
|
|
||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_second_episode_does_not_overwrite_encoder_fields(self, tmp_path, empty_lerobot_dataset_factory):
|
def test_second_episode_does_not_overwrite_encoder_fields(self, tmp_path, empty_lerobot_dataset_factory):
|
||||||
cfg = VideoEncoderConfig(vcodec="libsvtav1", g=2, crf=30, preset=12)
|
cfg = RGBEncoderConfig(vcodec="libsvtav1", g=2, crf=30, preset=12)
|
||||||
dataset = empty_lerobot_dataset_factory(
|
dataset = empty_lerobot_dataset_factory(
|
||||||
root=tmp_path / "ds", features=DUMMY_VIDEO_FEATURES, use_videos=True, rgb_encoder=cfg
|
root=tmp_path / "ds", features=DUMMY_VIDEO_FEATURES, use_videos=True, rgb_encoder=cfg
|
||||||
)
|
)
|
||||||
@@ -633,13 +633,13 @@ class TestEncoderConfigPersistence:
|
|||||||
|
|
||||||
|
|
||||||
class TestFromVideoInfo:
|
class TestFromVideoInfo:
|
||||||
"""``VideoEncoderConfig.from_video_info`` reconstructs an encoder config
|
"""``RGBEncoderConfig.from_video_info`` reconstructs an encoder config
|
||||||
from the ``video.*`` keys persisted in a dataset's ``info.json``.
|
from the ``video.*`` keys persisted in a dataset's ``info.json``.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@require_libsvtav1
|
@require_libsvtav1
|
||||||
def test_reconstructs_from_dummy_video_info(self):
|
def test_reconstructs_from_dummy_video_info(self):
|
||||||
cfg = VideoEncoderConfig.from_video_info(DUMMY_VIDEO_INFO)
|
cfg = RGBEncoderConfig.from_video_info(DUMMY_VIDEO_INFO)
|
||||||
|
|
||||||
# Canonical stream codec ``"av1"`` is aliased to the encoder name.
|
# Canonical stream codec ``"av1"`` is aliased to the encoder name.
|
||||||
assert cfg.vcodec == "libsvtav1"
|
assert cfg.vcodec == "libsvtav1"
|
||||||
@@ -651,7 +651,7 @@ class TestFromVideoInfo:
|
|||||||
assert cfg.video_backend == DUMMY_VIDEO_INFO["video.video_backend"]
|
assert cfg.video_backend == DUMMY_VIDEO_INFO["video.video_backend"]
|
||||||
# ``{}`` placeholder (typical after a merge with disagreeing sources)
|
# ``{}`` placeholder (typical after a merge with disagreeing sources)
|
||||||
# must not leak into the reconstructed config.
|
# must not leak into the reconstructed config.
|
||||||
assert cfg.extra_options == VideoEncoderConfig().extra_options
|
assert cfg.extra_options == RGBEncoderConfig().extra_options
|
||||||
|
|
||||||
|
|
||||||
# ─── Depth-specific encoding tests ────────────────────────────────────
|
# ─── Depth-specific encoding tests ────────────────────────────────────
|
||||||
|
|||||||
Reference in New Issue
Block a user