Source code for embodichain.data_pipeline.depth_video.codec

# ----------------------------------------------------------------------------
# Copyright (c) 2021-2026 DexForce Technology Co., Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------

"""Codec availability detection for depth video encoding.

Adapted from lerobot v0.6.0 ``pyav_utils.py`` (Apache-2.0). Probes the bundled
FFmpeg build through PyAV so the writer can pick a working encoder and degrade
gracefully (to numeric Parquet depth, PR #422) when HEVC is unavailable.
"""

from __future__ import annotations

import functools

import av

__all__ = ["DepthCodecError", "detect_depth_encoder", "resolve_depth_vcodec"]


[docs] class DepthCodecError(RuntimeError): """Raised when no suitable depth video codec is available."""
@functools.cache def get_codec(vcodec: str) -> av.codec.Codec | None: """PyAV write-mode ``Codec`` for *vcodec*, or ``None`` if unavailable.""" try: return av.codec.Codec(vcodec, "w") except Exception: return None
[docs] def detect_depth_encoder(vcodec: str | None = None) -> str | None: """Return an available depth video encoder name, or ``None``. Args: vcodec: Preferred codec name. If ``None`` or unavailable, fall back to the default preference list (``libx265`` then ``hevc``). Returns: The first available encoder name, or ``None`` if none are available. """ preference: list[str] = [] if vcodec: preference.append(vcodec) for name in ("libx265", "hevc"): if name not in preference: preference.append(name) for name in preference: codec = get_codec(name) if codec is not None and codec.type == "video": return name return None
[docs] def resolve_depth_vcodec(vcodec: str | None = None) -> str: """Return an available depth video encoder name, raising on failure. Args: vcodec: Preferred codec name. Returns: An available encoder name. Raises: DepthCodecError: If no depth video encoder is available in the bundled FFmpeg build. """ name = detect_depth_encoder(vcodec) if name is None: raise DepthCodecError( "No HEVC video encoder (libx265/hevc) is available in the bundled " "FFmpeg build; cannot write compressed depth videos. Install an " "FFmpeg build with libx265, or disable depth video to fall back to " "numeric depth features (PR #422)." ) return name