Skip to content

unienv_data.storages.video_storage

LOGGER module-attribute

LOGGER = logging.getLogger(__name__)

PyAvVideoReader

PyAvVideoReader(backend: ComputeBackend, filename: str, buffer_pixel_format: Optional[str] = None, hwaccel: Optional[Union[HWAccel, Literal['auto']]] = None, seek_mode: Literal['exact', 'approximate'] = 'exact', device: Optional[BDeviceType] = None)

HWAccel class-attribute instance-attribute

HWAccel = PyAvHWAccel

container instance-attribute

container = av.open(filename, mode='r', hwaccel=hwaccel)

video_stream instance-attribute

video_stream = self.container.streams.video[0]

video_reformatter instance-attribute

video_reformatter: Optional[VideoReformatter] = None

buffer_pixel_format instance-attribute

buffer_pixel_format = buffer_pixel_format

total_frames instance-attribute

total_frames = self.video_stream.frames

seek_mode instance-attribute

seek_mode = seek_mode

backend instance-attribute

backend = backend

device instance-attribute

device = device

keyframes instance-attribute

keyframes: Optional[ndarray] = None

available_hwdevices staticmethod

available_hwdevices() -> List[str]

get_auto_hwaccel staticmethod

get_auto_hwaccel() -> Optional[HWAccel]

keyframe_indices

keyframe_indices() -> np.ndarray

Frame indices of the keyframes, from a demux pass over the packets (no decoding).

frame_index_to_pts

frame_index_to_pts(frame_index: int) -> int

pts_to_frame_index

pts_to_frame_index(pts: int) -> int

seek

seek(frame_index: int)

tell

tell() -> int

close

close()

read

read(index: Union[IndexableType, BArrayType], total_length: int) -> BArrayType

TorchCodecVideoReader

TorchCodecVideoReader(backend: ComputeBackend, filename: str, buffer_pixel_format: Optional[str] = None, hwaccel: Optional[Union[HWAccel, Literal['auto']]] = None, seek_mode: Literal['exact', 'approximate'] = 'exact', device: Optional[BDeviceType] = None)

HWAccel class-attribute instance-attribute

HWAccel = Literal['beta', 'ffmpeg']

decoder instance-attribute

decoder = VideoDecoder(filename, device='cuda', seek_mode=seek_mode)

backend instance-attribute

backend = backend

device instance-attribute

device = device

buffer_pixel_format instance-attribute

buffer_pixel_format = buffer_pixel_format

get_auto_hwaccel staticmethod

get_auto_hwaccel() -> Optional[HWAccel]

close

close()

read

read(index: Union[IndexableType, ndarray], total_length: int) -> np.ndarray

VideoStorage

VideoStorage(single_instance_space: BoxSpace[BArrayType, BDeviceType, BDtypeType, BRNGType], cache_filename: Union[str, PathLike], seek_mode: Literal['exact', 'approximate'] = 'exact', hardware_acceleration: Optional[Union[Any, Literal['auto']]] = 'auto', codec: Union[str, Literal['auto']] = 'auto', decode_backend: Literal['torchcodec', 'pyav', 'auto'] = 'auto', cache_decoders: bool = False, file_ext: str = 'mp4', file_pixel_format: Optional[str] = None, buffer_pixel_format: str = 'rgb24', fps: int = 15, encoder_options: Optional[Dict[str, str]] = None, mutable: bool = True, capacity: Optional[int] = None, length: int = 0)

Bases: EpisodeStorageBase[BArrayType, BArrayType, BDeviceType, BDtypeType, BRNGType]

A storage for RGB or depth video data using video files If encoding RGB video - Set buffer_pixel_format to rgb24 - Set file_pixel_format to None (especially when running with nvenc codec) - Set file_ext to anything you like (e.g., "mp4", "avi", "mkv", etc.) If encoding depth video - Set buffer_pixel_format to gray16le (You can use rescale transform inside a TransformedStorage to convert depth values to this format, where dtype should be np.uint16) - if in meters, set min to 0 and max to 65.535 as the multiplication factor is 1000 (i.e., depth in mm) - Set file_pixel_format to gray16le - Set codec to a lossless codec that supports gray16le, e.g., ffv1 - Set file_ext to mkv encoder_options are passed to the encoder (e.g. {"crf": "28", "g": "15"}) and persisted in the metadata, so a loaded storage keeps encoding new segments the same way.

Random access: reading frame i decodes from the keyframe at or before i, so the cost of a random read grows with the GOP size (keyframe interval). Encoders default to long GOPs (libx264: 250 frames, i.e. one keyframe per episode); for buffers sampled at random positions set a short one, e.g. encoder_options={"g": "15"} (larger files, much cheaper random reads). Sequential and dense reads are not affected, and sparse reads within one file decode forward instead of seeking when no keyframe lies between two requested frames (the PyAV reader indexes each file's keyframes once).

PyAV_LOG_LEVEL class-attribute instance-attribute

PyAV_LOG_LEVEL = av.logging.WARNING

single_file_ext class-attribute instance-attribute

single_file_ext = None

pending_segment_length property

pending_segment_length: int

has_open_segment property

has_open_segment: bool

seek_mode instance-attribute

seek_mode = seek_mode

hwaccel instance-attribute

hwaccel = hardware_acceleration

codec instance-attribute

codec = self.get_auto_codec() if codec == 'auto' else codec

decode_backend instance-attribute

decode_backend = decode_backend

fps instance-attribute

fps = fps

encoder_options instance-attribute

encoder_options = None if encoder_options is None else {str(k): str(v) for k, v in encoder_options.items()}

file_pixel_format instance-attribute

file_pixel_format = file_pixel_format

buffer_pixel_format instance-attribute

buffer_pixel_format = buffer_pixel_format

cache_decoders instance-attribute

cache_decoders = cache_decoders

X265_MIN_BFRAME_CLIP_LENGTH class-attribute instance-attribute

X265_MIN_BFRAME_CLIP_LENGTH = 3

capacity instance-attribute

capacity = capacity

cache_filename property

cache_filename: Union[str, PathLike]

is_multiprocessing_safe property

is_multiprocessing_safe: bool

is_mutable instance-attribute

is_mutable = mutable

backend property

backend: ComputeBackend[BArrayType, BDeviceType, BDtypeType, BRNGType]

device property

device: Optional[BDeviceType]

single_instance_space instance-attribute

single_instance_space = single_instance_space

file_ext instance-attribute

file_ext = file_ext

length instance-attribute

length = length if capacity is None else capacity

create classmethod

create(single_instance_space: BoxSpace[BArrayType, BDeviceType, BDtypeType, BRNGType], *args, seek_mode: Literal['exact', 'approximate'] = 'exact', hardware_acceleration: Optional[Union[Any, Literal['auto']]] = 'auto', codec: Union[str, Literal['auto']] = 'auto', decode_backend: Literal['torchcodec', 'pyav', 'auto'] = 'auto', cache_decoders: bool = False, file_ext: str = 'mp4', file_pixel_format: Optional[str] = None, buffer_pixel_format: str = 'rgb24', fps: int = 15, encoder_options: Optional[Dict[str, str]] = None, capacity: Optional[int] = None, cache_path: Optional[str] = None, multiprocessing: bool = False, **kwargs) -> VideoStorage[BArrayType, BDeviceType, BDtypeType, BRNGType]

load_from classmethod

load_from(path: Union[str, PathLike], single_instance_space: BoxSpace[BArrayType, BDeviceType, BDtypeType, BRNGType], *, seek_mode: Literal['exact', 'approximate'] = 'exact', hardware_acceleration: Optional[Union[Any, Literal['auto']]] = 'auto', codec: Union[str, Literal['auto']] = 'auto', decode_backend: Literal['torchcodec', 'pyav', 'auto'] = 'auto', cache_decoders: bool = False, capacity: Optional[int] = None, read_only: bool = True, multiprocessing: bool = False, **kwargs) -> VideoStorage[BArrayType, BDeviceType, BDtypeType, BRNGType]

open_segment_writer

open_segment_writer() -> _VideoSegmentWriter

mark_segment_start

mark_segment_start(start_index)

append

append(frame)

mark_segment_end

mark_segment_end()

abort_segment

abort_segment()

get_segments

get_segments()

get

get(index: Union[IndexableType, BArrayType])

get_auto_codec staticmethod

get_auto_codec(base: Optional[str] = None) -> str

get_cached_decoder

get_cached_decoder(filename: str)

get_from_file

get_from_file(filename: str, index: Union[IndexableType, BArrayType], total_length: int) -> BArrayType

remove_index_range

remove_index_range(start_index: int, end_index: int)

set_to_file

set_to_file(filename: str, value: BArrayType)

dumps

dumps(path)

clear

clear()

close

close()

extend_length

extend_length(length)

shrink_length

shrink_length(length)

set

set(index, value)

get_start_end_filename_iter

get_start_end_filename_iter() -> Iterable[Tuple[int, int, str]]

Iterate over (start_idx, end_idx, filename) tuples, constructing filenames on the fly.

convert_read_index_to_filenames_and_offsets

convert_read_index_to_filenames_and_offsets(index: Union[IndexableType, BArrayType]) -> Tuple[int, List[Tuple[Union[str, os.PathLike], Union[int, BArrayType], Union[int, BArrayType]]]]

Convert an index (which can be an integer, slice, list of integers, or backend array) to a list of filenames and offsets. Each filename corresponds to an episode file, and the offset indicates the position within that episode.

set_to_file_safe

set_to_file_safe(filename: str, batched_value: BatchT)

Atomically write to a temporary file and rename it to the target filename.