API Reference

Complete API documentation for the on_demand_video_decoder package.

class accvlab.on_demand_video_decoder.PyNvGopDecoder

Bases: pybind11_object

GPU-accelerated video decoder with GOP-level random access.

Do not instantiate this class directly. Use CreateGopDecoder() to obtain an instance.

See also

CreateGopDecoder(): Factory function with full parameter documentation.

Decode(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvGopDecoder, filepaths: List[str], frame_ids: List[int], fastStreamInfos: List[accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.FastStreamInfo] = []) List[accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.DecodedFrameExt]

Decodes video file stream into YUV data.

This method performs GPU-accelerated decoding of video frames using NVIDIA hardware. It supports multiple video files and can decode specific frame IDs from each file. The method uses GOP-based decoding for efficient random access.

If you need RGB/BGR output, use DecodeN12ToRGB() instead.

Parameters:
  • filepaths – List of video file paths to decode from.

  • frame_ids – List of frame IDs to decode. Each frame ID corresponds to a specific frame in the video sequence.

  • fastStreamInfos – Optional list of FastStreamInfo objects containing pre-extracted stream information by GetFastInitInfo(). If provided, this can improve performance by avoiding stream analysis.

Returns:

List of DecodedFrameExt objects containing the decoded frame data.

Raises:
  • RuntimeError – If video files cannot be opened or decoded

  • ValueError – If frame_ids contain invalid indices

Example

>>> decoder = CreateGopDecoder(maxfiles=10)
>>> frames = decoder.Decode(['video1.mp4', 'video2.mp4'], [0, 10])
>>> # Convert to PyTorch tensors on GPU (NV12 layout: (height * 3 // 2, width), uint8)
>>> nv12_tensors = [torch.as_tensor(frame).clone() for frame in frames]
DecodeFromGOPList(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvGopDecoder, numpy_datas: List[numpy.ndarray[numpy.uint8]], filepaths: List[str], frame_ids: List[int]) List[accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.DecodedFrameExt]

Decodes multiple serialized GOP bundles into native YUV frames.

If you need RGB/BGR output, use DecodeFromGOPListRGB() instead.

Parameters:
  • numpy_datas – List of numpy arrays, each containing one serialized GOP bundle from GetGOPList() or LoadGopsToList() (one per video)

  • filepaths – List of source file paths, one for each requested frame

  • frame_ids – List of target frame IDs, one for each requested frame

Returns:

List of DecodedFrameExt objects containing decoded native YUV frame data

Raises:
  • RuntimeError – If GOP data is invalid or decoding fails

  • ValueError – If input arrays have mismatched dimensions

Example

>>> decoder = CreateGopDecoder(maxfiles=10)
>>> gop_list = decoder.GetGOPList(['video1.mp4', 'video2.mp4'], [0, 10])
>>> gop_data_list = [gop_data for gop_data, _, _ in gop_list]
>>> frames = decoder.DecodeFromGOPList(gop_data_list, ['video1.mp4', 'video2.mp4'], [0, 10])
>>> # Convert to PyTorch tensors on GPU (NV12 layout: (height * 3 // 2, width), uint8)
>>> nv12_tensors = [torch.as_tensor(frame).clone() for frame in frames]
DecodeFromGOPListRGB(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvGopDecoder, numpy_datas: List[numpy.ndarray[numpy.uint8]], filepaths: List[str], frame_ids: List[int], as_bgr: bool = False) List[accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.RGBFrame]

Decodes multiple serialized GOP bundles into RGB/BGR frames.

Parameters:
  • numpy_datas – List of numpy arrays, each containing one serialized GOP bundle from GetGOPList() or LoadGopsToList() (one per video)

  • filepaths – List of source file paths, one for each requested frame

  • frame_ids – List of target frame IDs, one for each requested frame

  • as_bgr – Whether to output in BGR format (True) or RGB format (False)

Returns:

List of RGBFrame objects containing the decoded RGB/BGR frames

Raises:
  • RuntimeError – If GOP data is invalid or decoding fails

  • ValueError – If input arrays have mismatched dimensions

Example

Ref to Sample: samples/SampleDemuxerDecoderSeparationAccess.py

>>> decoder = CreateGopDecoder(maxfiles=10)
>>> gop_list = decoder.GetGOPList(['video1.mp4', 'video2.mp4'], [0, 10])
>>> gop_data_list = [gop_data for gop_data, _, _ in gop_list]
>>> rgb_frames = decoder.DecodeFromGOPListRGB(
...     gop_data_list, ['video1.mp4', 'video2.mp4'], [0, 10], as_bgr=True)
>>> # Convert to PyTorch tensors on GPU (shape (height, width, 3), uint8)
>>> rgb_tensors = [torch.as_tensor(frame).clone() for frame in rgb_frames]
DecodeFromGOPRGB(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvGopDecoder, numpy_data: numpy.ndarray[numpy.uint8], filepaths: List[str], frame_ids: List[int], as_bgr: bool = False) List[accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.RGBFrame]

Warning

Deprecated — will be removed in version 0.3.0. Use GetGOPList() + DecodeFromGOPListRGB() instead; this method is kept temporarily for backwards compatibility.

Decodes a merged serialized GOP bundle into RGB frames without demuxing again.

Parameters:
  • numpy_data – Numpy array containing a merged serialized GOP bundle. No current API produces data in this format anymore — do not use this method.

  • filepaths – List of video file paths (for metadata purposes)

  • frame_ids – List of frame IDs to decode from the bundle

  • as_bgr – Whether to output in BGR format (True) or RGB format (False)

Returns:

List of RGBFrame objects containing the decoded and color-converted frame data

Raises:
  • RuntimeError – If GOP data is invalid or decoding fails

  • ValueError – If frame_ids don’t match the GOP data

DecodeFromPacketListInitialize(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvGopDecoder, codec_ids: List[int]) int

Warning

Under development — API is unstable and subject to change without notice. Do not use in production code.

Initializes NvDecoder instances for video files.

This method creates NvDecoder instances for each video file, preparing them for efficient decoding operations. It is used before DecodeFromPacketListRGB().

Parameters:

codec_ids – List of video codec IDs

Returns:

0 if initialization successful

Raises:

Example

Ref to Sample: samples/SampleDecodeFromBinaryData.py

DecodeFromPacketListRGB(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvGopDecoder, numpy_datas: List[List[numpy.ndarray[numpy.uint8]]], packet_idxs: List[List[int]], widths: List[int], heights: List[int], frame_ids: List[int], as_bgr: bool = False) List[accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.RGBFrame]

Warning

Under development — API is unstable and subject to change without notice. Do not use in production code.

Decodes video packets into RGB frames from raw per-frame packet data arrays.

This advanced interface takes one list of numpy arrays per frame, holding that frame’s raw packet data — possibly produced by an external demuxer — and decodes them directly, without the serialized GOP bundle format used by GetGOPList().

Parameters:
  • numpy_datas – List of lists of numpy arrays containing binary packet data for each frame. Each inner list contains numpy arrays for packets of one frame. The function automatically extracts packet sizes and data pointers from these arrays.

  • packet_idxs – List of lists containing decode indices for each frame

  • widths – List of frame widths for each frame

  • heights – List of frame heights for each frame

  • frame_ids – List of frame IDs to decode

  • as_bgr – Whether to output in BGR format (True) or RGB format (False)

Returns:

List of decoded RGB/BGR frames

Raises:
  • RuntimeError – If packet data is invalid or decoding fails

  • ValueError – If input arrays have mismatched dimensions

Example

Ref to Sample: samples/SampleDecodeFromBinaryData.py

DecodeN12ToRGB(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvGopDecoder, filepaths: List[str], frame_ids: List[int], as_bgr: bool = False, fastStreamInfos: List[accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.FastStreamInfo] = []) List[accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.RGBFrame]

Decodes video file stream into RGB/BGR data.

This method performs GPU-accelerated decoding and color space conversion from YUV to RGB/BGR format.

Parameters:
  • filepaths – List of video file paths to decode from

  • frame_ids – List of frame IDs to decode from the video files

  • as_bgr – Whether to output in BGR format (True) or RGB format (False). BGR is commonly used in OpenCV applications.

  • fastStreamInfos – Optional list of FastStreamInfo objects containing pre-extracted stream information by GetFastInitInfo(). If provided, this can improve performance by avoiding stream analysis.

Returns:

List of RGBFrame objects containing the decoded and color-converted frame data.

Raises:
  • RuntimeError – If video files cannot be opened or decoded

  • ValueError – If frame_ids contain invalid indices

Example

Ref to Sample: samples/SampleRandomAccess.py and samples/SampleRandomAccessWithFastInit.py

>>> decoder = CreateGopDecoder(maxfiles=10)
>>> rgb_frames = decoder.DecodeN12ToRGB(['video.mp4', 'video2.mp4'], [0, 10], as_bgr=True)
>>> # Convert to PyTorch tensors on GPU (shape (height, width, 3), uint8)
>>> rgb_tensors = [torch.as_tensor(frame).clone() for frame in rgb_frames]
GetGOPList(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvGopDecoder, filepaths: List[str], frame_ids: List[int], fastStreamInfos: List[accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.FastStreamInfo] = []) list

For each video, extracts the GOP(Group of Pictures) containing the requested frame and returns it as one serialized GOP bundle (numpy object) per video.

Note

This method performs CPU-side demuxing only and does not use any GPU resources. Pass the returned bundles to DecodeFromGOPListRGB() (or DecodeFromGOPList() for YUV output) to run the actual decode step on GPU.

Parameters:
  • filepaths – List of video file paths to extract GOP data from

  • frame_ids – List of frame IDs to extract GOP data for (one per video)

  • fastStreamInfos – Optional list of FastStreamInfo objects containing pre-extracted stream information by GetFastInitInfo(). If provided, this can improve performance by avoiding stream analysis.

Returns:

List of tuples, one per video file, each containing

  • serialized GOP bundle (numpy object) for that video

  • list with the first frame ID of the extracted GOP

  • list with the length (frame count) of the extracted GOP

Treat the bundle as an opaque blob: pass it to DecodeFromGOPListRGB() / DecodeFromGOPList() to decode any frame within the GOP range [first_frame_id, first_frame_id + gop_len), or persist it with SaveGopToFile() and reload it with LoadGopsToList().

Raises:

RuntimeError – If video files cannot be opened or GOP extraction fails

Example

Ref to Sample: samples/SampleDemuxerDecoderSeparationAccess.py

>>> decoder = CreateGopDecoder(maxfiles=10)
>>> results = decoder.GetGOPList(
...     ['video1.mp4', 'video2.mp4'],
...     [0, 10]
... )
>>> for i, (gop_data, first_ids, gop_lens) in enumerate(results):
...     print(f"Video {i}: GOP data size = {len(gop_data)}")
...     print(f"  First frame IDs: {first_ids}")
...     print(f"  GOP lengths: {gop_lens}")
LoadGopsToList(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvGopDecoder, file_paths: List[str]) list

Load serialized GOP bundles from multiple binary files and return as a list of numpy arrays.

This method loads serialized GOP bundles from binary files (previously saved with SaveGopToFile()) and returns one bundle (numpy array) per file, ready to be decoded with DecodeFromGOPListRGB() or DecodeFromGOPList().

Parameters:

file_paths – List of paths to GOP binary files to load

Returns:

List of numpy arrays, each containing the serialized GOP bundle from one file, in the same format as returned by GetGOPList().

Raises:
  • RuntimeError – If any file cannot be read or has invalid format

  • ValueError – If file_paths is empty or files have invalid GOP format

Example

Ref to Sample: samples/SampleDecodeFromGopFiles.py

>>> # GOP files previously saved with SaveGopToFile()
>>> gop_data_list = decoder.LoadGopsToList(['gop_0.bin', 'gop_1.bin'])
>>> frames = decoder.DecodeFromGOPListRGB(
...     gop_data_list, ['v1.mp4', 'v2.mp4'], [0, 10], as_bgr=True)
>>> rgb_tensors = [torch.as_tensor(frame).clone() for frame in frames]
release_decoder(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvGopDecoder) None

Release all decoder instances to free up GPU memory.

This method clears all decoder instances, which releases NvDecoder instances and their GPU frame buffers

This is useful for freeing GPU memory occupied by decoder instances.

Note: After calling this method, decoder instances will need to be re-created on the next decode operation.

Example

>>> decoder = CreateGopDecoder(maxfiles=10)
>>> frames = decoder.Decode(['video1.mp4'], [0, 10, 20])
>>> tensors = [torch.as_tensor(frame).clone() for frame in frames]
>>> decoder.release_decoder()  # Free decoder instances
release_device_memory(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvGopDecoder) None

Release GPU device memory pool to free up GPU memory.

This method releases the GPU memory pool and resets the pool state. This is useful for temporarily freeing excessive GPU memory usage.

Note: After calling this method, the memory pool will need to be re-allocated on the next decode operation.

Example

>>> decoder = CreateGopDecoder(maxfiles=10)
>>> frames = decoder.Decode(['video1.mp4'], [0, 10, 20])
>>> tensors = [torch.as_tensor(frame).clone() for frame in frames]
>>> decoder.release_device_memory()  # Free GPU memory pool
class accvlab.on_demand_video_decoder.PyNvSampleReader

Bases: pybind11_object

GPU-accelerated video decoder heavily optimized for sequential (stream) access.

Designed for temporal models and sequential video analysis where frames are accessed in order.

Do not instantiate this class directly. Use CreateSampleReader() to obtain an instance.

Decode(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvSampleReader, filepaths: List[str], frame_ids: List[int]) List[accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.DecodedFrameExt]

Decodes video frames into YUV data.

This method performs GPU-accelerated decoding of specific frames from multiple video files.

If you need RGB/BGR output, use DecodeN12ToRGB() instead.

Parameters:
  • filepaths – List of video file paths to decode from

  • frame_ids – List of frame IDs to decode from the video files

Returns:

List of DecodedFrameExt objects containing the decoded frame data.

Raises:
  • RuntimeError – If video files cannot be decoded or frame IDs are invalid

  • ValueError – If frame_ids contain invalid indices or filepaths is empty

Example

>>> reader = CreateSampleReader(num_of_set=2, num_of_file=3)
>>> frames = reader.Decode(['video1.mp4', 'video2.mp4'], [0, 10])
>>> # Convert to PyTorch tensors on GPU (NV12 layout: (height * 3 // 2, width), uint8)
>>> nv12_tensors = [torch.as_tensor(frame).clone() for frame in frames]
DecodeN12ToRGB(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvSampleReader, filepaths: List[str], frame_ids: List[int], as_bgr: bool = False) List[accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.RGBFrame]

Decodes video frames and converts them to RGB/BGR format.

This method performs GPU-accelerated decoding and color space conversion from YUV to RGB/BGR format for multiple video files.

If you need asynchronous decoding with prefetching, use DecodeN12ToRGBAsync() instead.

Parameters:
  • filepaths – List of video file paths to decode from

  • frame_ids – List of frame IDs to decode from the video files

  • as_bgr – Whether to output in BGR format (True) or RGB format (False). BGR is commonly used in OpenCV applications.

Returns:

List of RGBFrame objects containing the decoded and color-converted frame data.

Raises:
  • RuntimeError – If video files cannot be decoded or frame IDs are invalid

  • ValueError – If frame_ids contain invalid indices or filepaths is empty

Example

Ref to Sample: samples/SampleStreamAccess.py

>>> reader = CreateSampleReader(num_of_set=2, num_of_file=3)
>>> rgb_frames = reader.DecodeN12ToRGB(['video1.mp4', 'video2.mp4'], [0, 10], as_bgr=True)
>>> # Convert to PyTorch tensors on GPU (shape (height, width, 3), uint8)
>>> rgb_tensors = [torch.as_tensor(frame).clone() for frame in rgb_frames]
DecodeN12ToRGBAsync(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvSampleReader, filepaths: List[str], frame_ids: List[int], as_bgr: bool = False) None

Asynchronously decode video frames and convert them to RGB/BGR format.

This method submits a decode task to a background thread and returns immediately. The decoded frames will be stored in an internal buffer and can be retrieved using DecodeN12ToRGBAsyncGetBuffer().

If you do not need asynchronous prefetching, use DecodeN12ToRGB() instead.

Important

Buffer Clearing Behavior: Calling this method will clear any pending results from the internal buffer. You MUST ensure that you have already retrieved all buffered results using DecodeN12ToRGBAsyncGetBuffer before calling this method again. Otherwise, pending decoded frames will be discarded and cannot be recovered.

Deep Copy Requirement: After retrieving frames via DecodeN12ToRGBAsyncGetBuffer, you MUST ensure that the frames have been deep-copied (e.g., using PyTorch’s clone(), or other deep-copy operations) or have been fully consumed by post-processing operations (e.g., resize) before calling DecodeN12ToRGBAsync again. This is because RGBFrame objects use zero-copy semantics and reference GPU memory from the internal memory pool. The memory pool may reuse the same GPU memory allocation for new decode operations, which could corrupt data if the previous frames are still being referenced.

Parameters:
  • filepaths – List of video file paths to decode from

  • frame_ids – List of frame IDs to decode from the video files

  • as_bgr – Whether to output in BGR format (True) or RGB format (False). BGR is commonly used in OpenCV applications.

Note

Only one async decode task can be pending at a time. If you call this method while a previous task is still running, it will wait for the previous task to complete and print a warning.

Example

Ref to Sample: samples/SampleStreamAsyncAccess.py

>>> reader = CreateSampleReader(num_of_set=2, num_of_file=3)
>>> reader.DecodeN12ToRGBAsync(['video1.mp4', 'video2.mp4'], [0, 10], as_bgr=False)
>>> # Do other work...
>>> frames = reader.DecodeN12ToRGBAsyncGetBuffer(['video1.mp4', 'video2.mp4'], [0, 10], False)
>>> # Process frames (memory is zero-copy referenced by PyTorch tensors)
>>> tensor_list = [torch.as_tensor(frame, device='cuda').clone() for frame in frames]
>>> # Note: GPU memory is still allocated in the memory pool
>>> # Memory will be released when reader is destroyed or release_device_memory() is called
DecodeN12ToRGBAsyncGetBuffer(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvSampleReader, filepaths: List[str], frame_ids: List[int], as_bgr: bool = False) List[accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.RGBFrame]

Get decoded frames from the async decode buffer.

This method retrieves decoded frames from the internal buffer that were previously submitted via DecodeN12ToRGBAsync(). It validates that the requested filepaths and frame_ids match the buffered result.

Parameters:
  • filepaths – List of video file paths (must match the async request)

  • frame_ids – List of frame IDs (must match the async request)

  • as_bgr – BGR format flag (must match the async request)

Returns:

List of RGBFrame objects containing the decoded and color-converted frame data. The GPU memory is managed by the internal memory pool and uses zero-copy semantics.

Raises:

RuntimeError – If no matching result is found in buffer, validation fails, or decoding failed

Example

Ref to Sample: samples/SampleStreamAsyncAccess.py

>>> reader = CreateSampleReader(num_of_set=2, num_of_file=3)
>>> reader.DecodeN12ToRGBAsync(['video1.mp4', 'video2.mp4'], [0, 10], as_bgr=False)
>>> # Do other work...
>>> frames = reader.DecodeN12ToRGBAsyncGetBuffer(['video1.mp4', 'video2.mp4'], [0, 10], False)
>>> # Convert to PyTorch tensors (zero-copy, no memory allocation)
>>> tensor_list = [torch.as_tensor(frame, device='cuda').clone() for frame in frames]
>>> # Note: GPU memory is still in the memory pool, referenced by tensors
>>> # Memory will persist until reader is destroyed or release_device_memory() is called
clearAllReaders(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvSampleReader) None

Clear all video readers and release associated resources.

This method releases all video reader instances and their associated GPU resources. It should be called when the reader is no longer needed to free up GPU memory and other system resources.

Example

>>> reader = CreateSampleReader(num_of_set=2, num_of_file=3)
>>> frames = reader.Decode(['video1.mp4'], [0, 10, 20])
>>> tensors = [torch.as_tensor(frame).clone() for frame in frames]
>>> reader.clearAllReaders()  # Clean up resources
release_decoder(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvSampleReader) None

Release all video decoder instances to free up GPU memory.

This method clears all internal decoding sessions, releasing both the decoder instances and their GPU frame buffers. Note that this also releases the memory pools covered by release_device_memory().

This is useful for freeing GPU memory occupied by decoder instances.

Note: After calling this method, video readers will need to be re-created on the next decode operation.

Example

>>> reader = CreateSampleReader(num_of_set=2, num_of_file=3)
>>> frames = reader.Decode(['video1.mp4'], [0, 10, 20])
>>> tensors = [torch.as_tensor(frame).clone() for frame in frames]
>>> reader.release_decoder()  # Free decoder instances
release_device_memory(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvSampleReader) None

Release GPU device memory pool to free up GPU memory.

This method releases the GPU memory pool and resets the pool state. This is useful for temporarily freeing excessive GPU memory usage.

Note: After calling this method, the memory pool will need to be re-allocated on the next decode operation.

Example

>>> reader = CreateSampleReader(num_of_set=2, num_of_file=3)
>>> frames = reader.Decode(['video1.mp4'], [0, 10, 20])
>>> tensors = [torch.as_tensor(frame).clone() for frame in frames]
>>> reader.release_device_memory()  # Free GPU memory pool
class accvlab.on_demand_video_decoder.PyNvBatchAsyncStreamReader

Bases: pybind11_object

GPU-accelerated 2D async stream video decoder.

Submits a 2D decode request (V videos x F frames per video) to a background worker thread and returns the decoded frames as List[List[RGBFrame]] indexed [v][f]: submit with Decode(), then retrieve with GetBuffer(). See those two methods for the async usage contracts.

If you only need one frame per video per call, use PyNvSampleReader instead.

Do not instantiate this class directly. Use CreateBatchAsyncStreamReader() to obtain an instance.

See also

samples/SampleBatchAsyncStreamAccess.py for the canonical prefetch loop.

Decode(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvBatchAsyncStreamReader, filepaths: List[str], frame_ids: List[List[int]], as_bgr: bool = False) None

Submit an async 2D decode task. Returns immediately.

If you only need one frame per video per call, use PyNvSampleReader instead.

Parameters:
  • filepaths – List of video file paths. len(filepaths) <= num_of_file.

  • frame_ids – 2D list of frame ids. len(frame_ids) == len(filepaths); each inner list must be the same length (no jagged inner dims) and <= max_frames_per_decode_call. frame_ids[v][f] is the f-th frame requested for video v.

  • as_bgr – Output BGR (True) or RGB (False).

Raises:

RuntimeError – invalid input dimensions, exceeded construction limits, jagged inner lengths, or non-positive sizes.

Note

Discards prior result. At most one task can be in flight and the internal result buffer holds a single result. Calling Decode() unconditionally invalidates any prior buffered result. If a previous task is still running, it is joined first (with a warning to stderr) and its result discarded. Always pair every Decode() with a matching GetBuffer() for results you want to keep.

Note

Memory sizing. Each video slot’s output buffer is sized lazily on the first Decode() to that slot and reallocated automatically if a later call brings a higher resolution to the same slot. Videos within one call may have different resolutions (e.g. mixed-resolution camera rigs), but the F frames of any given video must share the same shape — normally true since they come from a single video file.

Warning

Lifetime contract. Frames previously returned by GetBuffer() become invalid as soon as you call Decode() again. Clone everything you need to keep BEFORE this call. See GetBuffer() for details.

GetBuffer(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvBatchAsyncStreamReader, filepaths: List[str], frame_ids: List[List[int]], as_bgr: bool = False) List[List[accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.RGBFrame]]

Block until the pending async task completes; return decoded frames.

Parameters:
  • filepaths – List of video file paths. Must exactly match the request passed to the previous Decode() call.

  • frame_ids – 2D list of frame ids. Must exactly match the request passed to the previous Decode() call.

  • as_bgr – Output format flag. Must exactly match the request passed to the previous Decode() call.

Returns:

A nested list List[List[RGBFrame]] indexed [v][f], mirroring the shape of the input frame_ids. Each RGBFrame.shape == (H, W, 3), dtype == uint8, lives in GPU memory, and is a zero-copy view into the reader’s internal aggregator pool.

Raises:

RuntimeError – No pending task and empty buffer; or request parameters do not match the buffered result (the result is then consumed and unrecoverable — same semantics as the 1D async API). Worker-side exceptions (file not found, invalid frame id, resolution mismatch across V) are propagated unchanged.

Note

Contract 1 — GPU-ready on return. The worker performs cuStreamSynchronize before pushing the result, so by the time this call returns, all decoder kernels and D2D copies are complete on the GPU. Downstream torch / CUDA ops can read the frames on any stream without further user-level synchronization.

Warning

Contract 2 — Invalidated on next Decode(). The returned RGBFrame objects share memory with the reader’s internal pool. Submitting the next Decode() reuses that memory for the new batch. You MUST clone (e.g. torch.as_tensor(frame, device="cuda").clone()) every frame you want to keep BEFORE calling Decode() again. Skipping the clone leads to silent data corruption — PyTorch tensors will not know their backing memory was overwritten.

Example

Ref to Sample: samples/SampleBatchAsyncStreamAccess.py

>>> reader.Decode(files, frame_ids_a, as_bgr=False)
>>> out = reader.GetBuffer(files, frame_ids_a, as_bgr=False)
>>> tensors = [[torch.as_tensor(out[v][f], device="cuda").clone()
...             for f in range(F)] for v in range(V)]
>>> # Safe to call Decode() again — tensors own their own memory.
>>> reader.Decode(files, frame_ids_b, as_bgr=False)
clearAllReaders(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvBatchAsyncStreamReader) None

Clear all underlying video readers. Waits for pending async task first.

release_decoder(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvBatchAsyncStreamReader) None

Release all decoder instances. Readers are re-created lazily on next decode.

release_device_memory(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvBatchAsyncStreamReader) None

Release per-reader memory pools and the 2D aggregator pool. Decoder state is preserved for efficient forward decoding.

class accvlab.on_demand_video_decoder.PyNvBatchAsyncGopDecoder

Bases: pybind11_object

GPU-accelerated 2D async GOP-based video decoder.

Decodes V videos × F frames each from pre-serialized GOP bundles. Submit with DecodeFromGOPListRGB() / DecodeFromGOPList(), retrieve with the matching GetBuffer method.

Only one task (RGB or YUV) may be in flight at a time. Calling a new Decode while the previous one is still running joins it first (a warning is printed to stderr).

Do not instantiate directly — use CreateBatchAsyncGopDecoder().

See also

PyNvBatchAsyncStreamReader for stream-based (non-GOP) decoding.

DecodeFromGOPList(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvBatchAsyncGopDecoder, numpy_datas: List[List[numpy.ndarray[numpy.uint8]]], filepaths: List[str], frame_ids: List[List[int]]) None

Submit an async 2D YUV decode from serialized GOP bundles. Returns immediately.

Same numpy_datas/filepath/frame_ids semantics as DecodeFromGOPListRGB. Output is DecodedFrameExt (NV12 / P016 / YUV444).

DecodeFromGOPListGetBuffer(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvBatchAsyncGopDecoder, filepaths: List[str], frame_ids: List[List[int]]) List[List[accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.DecodedFrameExt]]

Block until the pending YUV task completes; return decoded frames.

Returns:

List[List[DecodedFrameExt]] indexed [v][f]. Each frame references the internal aggregator pool — clone before calling DecodeFromGOPList() again.

DecodeFromGOPListRGB(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvBatchAsyncGopDecoder, numpy_datas: List[List[numpy.ndarray[numpy.uint8]]], filepaths: List[str], frame_ids: List[List[int]], as_bgr: bool = False) None

Submit an async 2D RGB decode from serialized GOP bundles. Returns immediately.

Parameters:
  • numpy_datasList[List[np.ndarray]] shaped [V][gop_idx]. Each element is a 1-D uint8 numpy array containing a serialized GOP bundle (one output element of GetGOPList). All bundles for video v together must cover every frame in frame_ids[v].

  • filepaths – List of video file paths, len == V.

  • frame_ids – 2-D list of frame ids [V][F]. All inner lists must have the same length. Order is preserved in the output (output [v][f] corresponds to frame_ids[v][f]).

  • as_bgr – Output BGR (True) or RGB (False).

Warning

Lifetime contract. Frames returned by the previous DecodeFromGOPListRGBGetBuffer() are invalidated once this method is called again. Clone before re-submitting.

DecodeFromGOPListRGBGetBuffer(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvBatchAsyncGopDecoder, filepaths: List[str], frame_ids: List[List[int]], as_bgr: bool = False) List[List[accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.RGBFrame]]

Block until the pending RGB task completes; return decoded frames.

Args must exactly match those passed to the preceding DecodeFromGOPListRGB() call.

Returns:

List[List[RGBFrame]] indexed [v][f], matching the shape of frame_ids. Each RGBFrame lives in GPU memory and is a zero-copy view into the internal aggregator pool — clone before calling DecodeFromGOPListRGB() again.

Raises:

RuntimeError – No pending task / empty buffer; result type mismatch (YUV result consumed by RGB getter); request parameter mismatch; or any worker-side decode error.

Note

This call performs a single cuStreamSynchronize on the shared decode stream, so all decode kernels and D2D copies are GPU-complete by the time it returns.

release_decoder(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvBatchAsyncGopDecoder) None

Release the internal GOP decoder instance. It is re-created lazily on the next decode call.

release_device_memory(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.PyNvBatchAsyncGopDecoder) None

Release aggregator GPU memory pools (RGB and YUV) and the internal GOP decoder memory pool. Decoder state is preserved.

class accvlab.on_demand_video_decoder.FastStreamInfo(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.FastStreamInfo)

Bases: pybind11_object

Pre-extracted stream metadata used to accelerate the demuxing stage.

Passing a FastStreamInfo to PyNvGopDecoder.Decode(), PyNvGopDecoder.DecodeN12ToRGB(), or PyNvGopDecoder.GetGOPList() allows the demuxer to skip the stream-probing step, reducing per-call latency. Obtain instances via GetFastInitInfo().

Note

A FastStreamInfo can be reused across multiple video files as long as they share the same encoding parameters (codec, resolution, frame rate, etc.). This is common in autonomous driving or robotics datasets where all clips are recorded from the same camera configuration. Reusing it across files with different parameters will cause undefined behavior during demuxing.

property avg_frame_rate_den

Average frame rate denominator

property avg_frame_rate_num

Average frame rate numerator

property codec_id

FFmpeg codec ID (AVCodecID enum value, e.g., AV_CODEC_ID_H264=27)

property codec_type

FFmpeg codec type (AVMediaType enum value)

property duration

Duration of the stream in time base units

property format

Pixel format (AVPixelFormat enum value)

property height

Video frame height in pixels

property r_frame_rate_den

Real frame rate denominator

property r_frame_rate_num

Real frame rate numerator

property start_time

Start time of the stream in time base units

property time_base_den

Time base denominator for timestamp calculations

property time_base_num

Time base numerator for timestamp calculations

property width

Video frame width in pixels

class accvlab.on_demand_video_decoder.DecodedFrameExt

Bases: pybind11_object

GetPtrToPlane(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.DecodedFrameExt, arg0: int) int

return pointer to base address for plane index :param planeIdx : index to the plane

property color_range
cuda(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.DecodedFrameExt) List[accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.CAIMemoryView]

return underlying views which implement CAI :param None: None

property dtype

Get the data type of the buffer

property format
framesize(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.DecodedFrameExt) int

return underlying views which implement CAI :param None: None

nvcv_image(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.DecodedFrameExt) List[accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.CAIMemoryView]

return underlying views which implement CAI :param None: None

property shape

Get the shape of the buffer as an array

property strides

Get the strides of the buffer

property timestamp
class accvlab.on_demand_video_decoder.RGBFrame(self: accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.RGBFrame, arg0: List[int], arg1: List[int], arg2: str, arg3: int, arg4: int, arg5: bool, arg6: bool)

Bases: pybind11_object

property data
property dataptr
property isBGR
property shape
property stride
accvlab.on_demand_video_decoder.CreateSampleReader(num_of_set: int, num_of_file: int, iGpu: int = 0, suppressNoColorRangeWarning: bool = False) PyNvSampleReader

Create a GPU-accelerated video decoder optimized for sequential (stream) access.

This factory function creates a PyNvSampleReader instance.

Parameters:
  • num_of_set – Number of samples (video-file sets) to keep cached. Use 1 for simple sequential access; use your batch size when iterating over the samples of a batch in a round-robin fashion (the same sample is accessed again every num_of_set-th call).

  • num_of_file – Maximum number of video files per sample

  • iGpu – GPU device ID to use for decoding (0 for primary GPU)

  • suppressNoColorRangeWarning – Suppress warning when no color range can be extracted from video files (limited/MPEG range is assumed)

Returns:

PyNvSampleReader instance configured with the specified parameters

Raises:

RuntimeError – If GPU initialization fails or parameters are invalid

Example

>>> reader = CreateSampleReader(num_of_set=2, num_of_file=3, iGpu=0)
>>> frames = reader.Decode(['v0.mp4', 'v1.mp4'], [0, 10])
>>> # Convert to PyTorch tensors on GPU (NV12 layout: (height * 3 // 2, width), uint8)
>>> nv12_tensors = [torch.as_tensor(frame).clone() for frame in frames]

Note

The parameter num_of_set controls the decoding cycle. For a specific decoder instance, if you are decoding clipA, the input returns to clipA again after calling PyNvSampleReader.DecodeN12ToRGB() num_of_set times. If you are continuously decoding the same clip, set num_of_set to 1.

accvlab.on_demand_video_decoder.CreateBatchAsyncStreamReader(num_of_set: int, num_of_file: int, max_frames_per_decode_call: int, iGpu: int = 0, suppressNoColorRangeWarning: bool = False) PyNvBatchAsyncStreamReader

Create a PyNvBatchAsyncStreamReader for 2D async stream decoding.

This reader is async-only and 2D-only: it accepts a list of video files and a 2D list of frame ids (one list per video), submits the decode in the background, and returns the decoded frames as List[List[RGBFrame]] indexed [v][f].

Parameters:
  • num_of_set – Number of decoder slots per file.

  • num_of_file – Maximum number of videos per decode call (V upper bound).

  • max_frames_per_decode_call – Maximum number of frames per video per decode call (F upper bound). The internal aggregator pool is sized for this peak.

  • iGpu – GPU device id.

  • suppressNoColorRangeWarning – Suppress warning when no color range can be extracted (limited / MPEG range is assumed).

Returns:

PyNvBatchAsyncStreamReader instance configured with the specified parameters

Example

>>> reader = CreateBatchAsyncStreamReader(
...     num_of_set=1, num_of_file=6, max_frames_per_decode_call=4)
>>> reader.Decode(filepaths, frame_ids_2d, as_bgr=False)
>>> out = reader.GetBuffer(filepaths, frame_ids_2d, as_bgr=False)
>>> # Convert to PyTorch tensors on GPU (clone before the next Decode() call)
>>> tensors = [[torch.as_tensor(f).clone() for f in v] for v in out]
accvlab.on_demand_video_decoder.CreateBatchAsyncGopDecoder(maxfiles: int, max_frames_per_decode_call: int, iGpu: int = 0, suppressNoColorRangeWarning: bool = False) PyNvBatchAsyncGopDecoder

Create a PyNvBatchAsyncGopDecoder for 2D async GOP-based decoding.

Accepts pre-serialized GOP bundles (from GetGOPList()) and decodes the requested frames asynchronously. Both RGB and YUV output paths are provided.

Parameters:
  • maxfiles – Maximum number of videos per decode call (V upper bound).

  • max_frames_per_decode_call – Maximum number of frames per video per call (F upper bound).

  • iGpu – GPU device id.

  • suppressNoColorRangeWarning – Suppress warning when no color range can be extracted.

Returns:

PyNvBatchAsyncGopDecoder instance.

Example

>>> gop_datas = decoder.GetGOPList(filepaths, frame_ids)  # [v] → SerializedPacketBundle
>>> gop_dec = CreateBatchAsyncGopDecoder(maxfiles=6, max_frames_per_decode_call=4)
>>> numpy_datas = [[np.frombuffer(b.data, dtype=np.uint8)] for b in gop_datas]
>>> gop_dec.DecodeFromGOPListRGB(numpy_datas, filepaths, frame_ids_2d, as_bgr=False)
>>> out = gop_dec.DecodeFromGOPListRGBGetBuffer(filepaths, frame_ids_2d, as_bgr=False)
accvlab.on_demand_video_decoder.GetFastInitInfo(filepaths: List[str]) List[accvlab.on_demand_video_decoder._PyNvOnDemandDecoder.FastStreamInfo]

Extracts FastStreamInfo from a list of video files.

Parameters:

filepaths – List of video file paths to analyze

Returns:

List of FastStreamInfo objects, one per file

Raises:

RuntimeError – If files cannot be opened or stream information cannot be extracted

Example

>>> stream_infos = GetFastInitInfo(['video1.mp4', 'video2.mp4'])
>>> gop_list = decoder.GetGOPList(['video1.mp4', 'video2.mp4'], [0, 10], stream_infos)

See also

FastStreamInfo: Usage and reuse conditions.

accvlab.on_demand_video_decoder.SaveGopToFile(numpy_data: numpy.ndarray[numpy.uint8], dst_filepath: str) None

Saves one serialized GOP bundle (for a single video) to a binary file.

Serialized GOP bundles are obtained from PyNvGopDecoder.GetGOPList(), which returns one bundle (numpy object) per video. Call this function once per video to save each bundle. To reload the bundles later, use PyNvGopDecoder.LoadGopsToList().

Parameters:
  • numpy_data – Numpy object containing one serialized GOP bundle for a single video. This corresponds to a single element of the list returned by PyNvGopDecoder.GetGOPList()

  • dst_filepath – Destination file path where the bundle will be written

Raises:

Example

>>> gop_list = decoder.GetGOPList(['v0.mp4', 'v1.mp4'], [10, 20])
>>> for i, (packets, _, _) in enumerate(gop_list):
...     SaveGopToFile(packets, f'gop_{i}.bin')

See also

For advanced usage including hierarchical GOP storage with persistent index, see examples/demuxer_free_decode/gop_storage.py.

class accvlab.on_demand_video_decoder.CachedGopDecoder(decoder, cache_capacity, *, _key=None)[source]

Bases: object

GOP decoder with transparent GOP caching.

This class extends PyNvGopDecoder: all of its methods are available on this class, and GetGOPList() additionally accepts a useGOPCache parameter that caches serialized GOP bundles to avoid redundant demuxing when frames from the same GOP are requested multiple times. See GetGOPList() for the caching behavior.

Do not instantiate this class directly. Use CreateGopDecoder() to obtain an instance.

See also

PyNvGopDecoder: The underlying decoder class with full method documentation.

Initialize the cached GOP decoder.

Note

Do not instantiate this class directly. Use CreateGopDecoder() instead.

Parameters:

decoder (PyNvGopDecoder) – The internal decoder instance

Raises:

RuntimeError – If called directly instead of using CreateGopDecoder()

clear_cache()[source]

Clear all cached GOP data.

Call this method to free memory when cached data is no longer needed.

Return type:

None

get_cache_info()[source]

Get information about the current cache state.

Returns:

dict – Dictionary with cache statistics and per-file information

isCacheHit()[source]

Get cache hit status for each file in the last GetGOPList() call.

Returns:

List[bool] – List of booleans, one per file in the last GetGOPList() call. True indicates cache hit, False indicates cache miss. Returns empty list if GetGOPList() has not been called yet.

Example

>>> decoder = CreateGopDecoder(maxfiles=6, iGpu=0)
>>> files = ['video1.mp4', 'video2.mp4', 'video3.mp4']
>>> gops, first_ids, gop_lens = zip(*decoder.GetGOPList(files, [77, 77, 77], useGOPCache=True))
>>> cache_hits = decoder.isCacheHit()
>>> # cache_hits = [False, False, False]  # First call, all miss
>>>
>>> gops, first_ids, gop_lens = zip(*decoder.GetGOPList(files, [80, 80, 80], useGOPCache=True))
>>> cache_hits = decoder.isCacheHit()
>>> # cache_hits = [True, True, True]  # Second call in same GOP range, all hit
GetGOPList(filepaths, frame_ids, fastStreamInfos=[], useGOPCache=False)[source]

Extract serialized GOP bundles with optional caching support.

Same as PyNvGopDecoder.GetGOPList(), with an additional useGOPCache parameter.

When useGOPCache=True, cache hits are checked per file: only cache misses are demuxed, the cache is updated with the newly extracted bundles, and results are assembled in the same order as the input filepaths. A cache hit for a file occurs when the requested frame_id falls within that file’s previously cached GOP range (first_frame_id <= frame_id < first_frame_id + gop_len). When useGOPCache=False (default), the cache is bypassed.

Parameters:
  • filepaths (List[str]) – List of video file paths to extract GOP data from

  • frame_ids (List[int]) – List of frame IDs to extract GOP data for (one per file)

  • fastStreamInfos (List[Any], default: []) – Optional list of FastStreamInfo objects for fast initialization

  • useGOPCache (bool, default: False) – If True, enables GOP caching. Default is False.

Returns:

List[Tuple[ndarray, List[int], List[int]]] – List of tuples, one per video file, each containing

  • serialized GOP bundle (numpy array) for that video

  • list with the first frame ID of the extracted GOP

  • list with the length (frame count) of the extracted GOP

Example

>>> decoder = CreateGopDecoder(maxfiles=6, iGpu=0)
>>> files = ['video1.mp4', 'video2.mp4']
>>> # First call - fetches from video files
>>> gop_list = decoder.GetGOPList(files, [77, 77], useGOPCache=True)
>>> print(decoder.isCacheHit())  # [False, False]
>>>
>>> # Second call with frame_id in same GOP range - returns from cache
>>> gop_list = decoder.GetGOPList(files, [80, 80], useGOPCache=True)
>>> print(decoder.isCacheHit())  # [True, True]
>>>
>>> # Use with DecodeFromGOPListRGB
>>> gop_data_list = [data for data, _, _ in gop_list]
>>> frames = decoder.DecodeFromGOPListRGB(gop_data_list, files, [80, 80], True)
>>> # Convert to PyTorch tensors on GPU (shape (height, width, 3), uint8)
>>> rgb_tensors = [torch.as_tensor(frame).clone() for frame in frames]
__getattr__(name)[source]

Proxy all other attribute accesses to the internal decoder.

This ensures that all methods not explicitly overridden (like DecodeFromGOPListRGB(), etc.) are transparently forwarded.

Parameters:

name (str) – The attribute name to access

Returns:

Any – The attribute from the internal decoder

accvlab.on_demand_video_decoder.CreateGopDecoder(maxfiles, iGpu=0, suppressNoColorRangeWarning=False, gopCacheCapacity=None)[source]

Create a GPU-accelerated video decoder with GOP-level random access.

This factory function creates a CachedGopDecoder instance with transparent GOP caching support.

Parameters:
  • maxfiles (int) – Maximum number of unique files that can be processed concurrently

  • iGpu (int, default: 0) – GPU device ID to use for decoding (0 for primary GPU)

  • suppressNoColorRangeWarning (bool, default: False) – Suppress warning when no color range can be extracted from video files (limited/MPEG range is assumed)

  • gopCacheCapacity (Optional[int], default: None) – Maximum number of filepath entries kept in the Python GOP cache. None defaults to maxfiles. This capacity only affects calls with useGOPCache=True; each filepath stores the most recently requested serialized GOP bundle, and least recently used filepaths are evicted when the limit is exceeded.

Returns:

CachedGopDecoderCachedGopDecoder instance configured with the specified parameters

Raises:

RuntimeError – If parameters are invalid

Example

>>> decoder = CreateGopDecoder(maxfiles=3, iGpu=0)
>>> # Use with caching enabled
>>> (gops, first_ids, gop_lens), = decoder.GetGOPList(['v0.mp4'], [10], useGOPCache=True)
>>> # Subsequent calls with frame_id in same GOP return cached data
>>> (gops, first_ids, gop_lens), = decoder.GetGOPList(['v0.mp4'], [15], useGOPCache=True)
class accvlab.on_demand_video_decoder.Codec(value)[source]

Bases: Enum

Video codec enumeration matching CUDA Video Codec SDK codec IDs.

These values correspond to cudaVideoCodec enum values used by the underlying NVIDIA hardware decoder.

h264 = 4
hevc = 8
av1 = 11
class accvlab.on_demand_video_decoder.GopRef(shm_name: str, data_size: int, first_frame_id: int, gop_len: int)[source]

Bases: NamedTuple

Lightweight, picklable reference to GOP data in shared memory.

Designed to be passed through DataLoader IPC queues (tens of bytes) instead of the actual serialized GOP bundle (tens of KB). The main process calls SharedGopStore.get_batch() to read the referenced shm blocks as zero-copy numpy views.

shm_name

POSIX SharedMemory name for the data block.

data_size

Number of bytes of the serialized GOP bundle.

first_frame_id

First frame index covered by this GOP.

gop_len

Number of frames in this GOP.

Example

Ref to Sample: packages/on_demand_video_decoder/samples/SampleSharedGopStore.py — end-to-end usage of GopRef with SharedGopStore across DataLoader workers.

Create new instance of GopRef(shm_name, data_size, first_frame_id, gop_len)

class accvlab.on_demand_video_decoder.SharedGopStore(capacity, store_id, _create, *, _key=None)[source]

Bases: object

Cross-process shared GOP store backed by POSIX SharedMemory.

Stores serialized GOP bundles in per-GOP SharedMemory blocks. A small SharedMemory block holds the metadata table (index). File-based locking (flock) provides cross-process safety under spawn mode.

Capacity sizing: capacity must exceed the maximum number of GOPs that can be “in flight” (queued in the DataLoader + being consumed by the training loop):

min_capacity > (prefetch_factor * num_workers + 1) * batch_size * num_cameras

A recommended formula is batch_size * num_cameras * 10.

Note

Do not instantiate this class directly. Use create() (main process, before spawning workers) or attach() (worker processes) instead — these factories manage shared-memory creation and tear-down correctly.

Parameters:
  • capacity (int) – Maximum number of GOPs to cache.

  • store_id (int) – Unique identifier (typically LOCAL_RANK).

  • _create (bool) – Internal flag – use create() / attach().

Raises:

RuntimeError – If called directly instead of via create() / attach().

classmethod create(capacity, store_id=0)[source]

Allocate a new store. Call from main process before spawning workers.

Parameters:
  • capacity (int) – Max number of GOPs to cache.

  • store_id (int, default: 0) – Unique identifier (typically LOCAL_RANK).

Return type:

SharedGopStore

classmethod attach(capacity, store_id=0)[source]

Attach to an existing store. Call from worker processes.

Raises:

FileNotFoundError – If the store has not been created yet.

Return type:

SharedGopStore

lookup(video_path, frame_id)[source]

Lock-free lookup for a cached GOP containing frame_id.

Returns a GopRef on hit, None on miss. Lock-free design means the worst case is a stale miss (one extra disk read), never a correctness issue.

Return type:

Optional[GopRef]

put(video_path, first_frame_id, gop_len, data)[source]

Store a serialized GOP bundle and return a GopRef.

Holds flock during eviction + insertion to guarantee atomicity. Performs a double-check after acquiring the lock (another worker may have inserted while we waited).

Return type:

GopRef

read(ref)[source]

Zero-copy uint8 numpy view of the serialized GOP bundle in shared memory.

Caches SharedMemory handles per-process to avoid repeated shm_open() system calls.

Return type:

ndarray

get_batch(refs)[source]

Read a batch of GOPs from shared memory (zero-copy).

Call once per training iteration from the main process. Holds flock during the entire operation so that no worker can evict a block while handles are being opened. After opening, orphaned shm blocks (evicted but not yet unlinked) are cleaned up.

Parameters:

refs (List[GopRef]) – Flat list of GopRef from DataLoader workers.

Returns:

List[ndarray] – List of zero-copy uint8 numpy views, same order as refs.

get_stats()[source]

Per-process cache statistics.

Return type:

dict

reset_stats()[source]

Reset per-process statistics counters.

Return type:

None

cleanup()[source]

Unlink all SharedMemory blocks and the lock file.

Call from the main process on shutdown.

Return type:

None

close()[source]

Close SharedMemory handles without unlinking.

Call from worker processes before exit.

Return type:

None

accvlab.on_demand_video_decoder.drop_videos_cache(filepaths)[source]

Evict cached pages for multiple video files from Linux paged cache.

Uses posix_fadvise with POSIX_FADV_DONTNEED flag to advise the kernel that these pages are no longer needed, causing the kernel to remove them from the page cache. This is useful when switching video datasets during training to release memory cache occupied by old videos.

This function uses fail-fast mode: it stops processing and returns immediately when the first error occurs.

Parameters:

filepaths (List[str]) – List of video file paths.

Returns:

DropCacheStatus – DropCacheStatus enum

  • SUCCESS: all files processed successfully

  • PLATFORM_ERROR: not Linux platform

  • FILE_OPEN_FAILED: failed to open file (file not found, permission denied, etc.)

  • FADVISE_FAILED: posix_fadvise call failed

  • UNKNOWN_ERROR: unexpected error occurred

Note

  • This is an advisory operation; the kernel may ignore the request depending on system state.

  • This function only works on Linux systems; other platforms return PLATFORM_ERROR.

  • Processing stops at the first error (fail-fast mode).

  • File contents are not affected; only the in-memory cached copy is released.

Warning

The actual cache eviction behavior is influenced by system environment factors:

  • System memory pressure and kernel memory management policies affect whether the advisory is honored.

  • On shared systems with many concurrent processes, cache state may change due to other processes’ I/O activities.

Example

>>> import accvlab.on_demand_video_decoder as nvc
>>> from accvlab.on_demand_video_decoder import DropCacheStatus
>>> video_files = ["/path/to/video1.mp4", "/path/to/video2.mp4"]
>>> status = nvc.drop_videos_cache(video_files)
>>> if status == DropCacheStatus.SUCCESS:
...     print("Successfully dropped cache for all files")
>>> elif status == DropCacheStatus.PLATFORM_ERROR:
...     print("Platform not supported (not Linux)")
>>> elif status == DropCacheStatus.FILE_OPEN_FAILED:
...     print("Failed to open file (not found or permission denied)")
>>> elif status == DropCacheStatus.FADVISE_FAILED:
...     print("posix_fadvise call failed")
>>> elif status == DropCacheStatus.UNKNOWN_ERROR:
...     print("Unexpected error occurred")
class accvlab.on_demand_video_decoder.DropCacheStatus(value)[source]

Bases: Enum

Status codes for drop_videos_cache operations.

SUCCESS = 0
PLATFORM_ERROR = 1
FILE_OPEN_FAILED = 2
FADVISE_FAILED = 3
UNKNOWN_ERROR = 4