Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Submodule pybind11 updated 178 files
Original file line number Diff line number Diff line change
Expand Up @@ -541,8 +541,10 @@ void Init_PyNvGopDecoder(py::module& m) {
// Create numpy array from serialized data for this video
auto capsule = py::capsule(bundle.data.release(),
[](void* ptr) { delete[] static_cast<uint8_t*>(ptr); });
py::array_t<uint8_t> numpy_data(
bundle.size, static_cast<uint8_t*>(capsule.get_pointer()), capsule);
py::array_t<uint8_t> numpy_data({static_cast<py::ssize_t>(bundle.size)},
{static_cast<py::ssize_t>(sizeof(uint8_t))},
static_cast<uint8_t*>(capsule.get_pointer()),
capsule);

// Create tuple (numpy_data, first_frame_ids, gop_lens) for this video
py::tuple video_tuple =
Expand Down Expand Up @@ -1218,7 +1220,9 @@ void Init_PyNvGopDecoder(py::module& m) {
py::capsule(raw_ptr, [](void* ptr) { delete[] static_cast<uint8_t*>(ptr); });

// Create numpy array
py::array_t<uint8_t> numpy_data(size, raw_ptr, capsule);
py::array_t<uint8_t> numpy_data({static_cast<py::ssize_t>(size)},
{static_cast<py::ssize_t>(sizeof(uint8_t))}, raw_ptr,
capsule);

result_list.append(std::move(numpy_data));
}
Expand Down
27 changes: 27 additions & 0 deletions packages/on_demand_video_decoder/tests/test_gop_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
including cache hit/miss scenarios, cache management, and data correctness.
"""

from pathlib import Path

import numpy as np
import pytest
import sys
import torch
Expand Down Expand Up @@ -47,6 +50,17 @@ def _gop_ranges(gop_list):
return first_ids, gop_lens


def _assert_contiguous_byte_bundle(bundle: np.ndarray, expected: bytes) -> None:
assert isinstance(bundle, np.ndarray)
assert bundle.dtype == np.dtype(np.uint8)
assert bundle.ndim == 1
assert bundle.itemsize == 1
assert bundle.strides == (1,)
assert bundle.flags.c_contiguous
assert bundle.nbytes == len(expected)
assert bundle.tobytes() == expected


class TestGetGOPListCache:
"""Tests for GetGOPList with useGOPCache parameter."""

Expand Down Expand Up @@ -95,6 +109,19 @@ def test_getgoplist_basic(self, decoder, test_files_and_frames, use_cache):

print(f"✓ Test passed: Got {len(gop_list)} GOP bundles")

def test_gop_bundle_numpy_layout(self, decoder, tmp_path):
"""Serialized GOP bundles stay contiguous on NumPy 1.x and 2.x."""
sample_video = Path(utils.get_data_dir()) / "sample_clip" / "moving_shape_circle_h265.mp4"
bundle = decoder.GetGOPList([str(sample_video)], [10], useGOPCache=False)[0][0]

gop_path = tmp_path / "serialized.gop"
nvc.SaveGopToFile(bundle, str(gop_path))
expected = gop_path.read_bytes()
_assert_contiguous_byte_bundle(bundle, expected)

loaded = decoder.LoadGopsToList([str(gop_path)])[0]
_assert_contiguous_byte_bundle(loaded, expected)

def test_getgoplist_cache_hit(self, decoder, test_files_and_frames):
"""
Test GetGOPList cache hit scenario.
Expand Down