Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend PyDecoder unit tests #138

Merged
merged 2 commits into from
Feb 13, 2025
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
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

skbuild.setup(
name="python_vali",
version="4.2.8-0",
version="4.2.9-0",
description="Video Processing Library with full NVENC/NVDEC hardware acceleration",
long_description=open('README.md').read(),
long_description_content_type='text/markdown',
Expand Down
2 changes: 1 addition & 1 deletion src/python_vali/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
__copyright__ = "Copyright 2022, NVIDIA; Copyright 2023, Vision Labs LLC"
__credits__ = []
__license__ = "Apache 2.0"
__version__ = "4.2.8-0"
__version__ = "4.2.9-0"
__maintainer__ = "Roman Arzumanyan"
__email__ = "TODO"
__status__ = "Production"
Expand Down
21 changes: 14 additions & 7 deletions src/python_vali/src/PyDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ bool PyDecoder::DecodeSingleFrame(py::array& frame, TaskExecDetails& details,
PacketData& pkt_data,
std::optional<SeekContext> seek_ctx) {
if (IsAccelerated()) {
details.m_info = TaskExecInfo::FAIL;
return false;
}

Expand All @@ -108,6 +109,7 @@ bool PyDecoder::DecodeSingleSurface(Surface& surf, TaskExecDetails& details,
PacketData& pkt_data,
std::optional<SeekContext> seek_ctx) {
if (!IsAccelerated()) {
details.m_info = TaskExecInfo::FAIL;
return false;
}

Expand Down Expand Up @@ -383,8 +385,10 @@ void Init_PyDecoder(py::module& m) {

auto res =
self.DecodeSingleSurface(surf, details, pkt_data, seek_ctx);
self.m_event->Record();
self.m_event->Wait();
if (res) {
self.m_event->Record();
self.m_event->Wait();
}
return std::make_tuple(res, details.m_info);
},
py::arg("surf"), py::arg("seek_ctx") = std::nullopt,
Expand All @@ -407,7 +411,7 @@ void Init_PyDecoder(py::module& m) {

auto res =
self.DecodeSingleSurface(surf, details, pkt_data, seek_ctx);
if (record_event) {
if (res && record_event) {
self.m_event->Record();
}
return std::make_tuple(res, details.m_info,
Expand Down Expand Up @@ -439,8 +443,10 @@ void Init_PyDecoder(py::module& m) {

auto res =
self.DecodeSingleSurface(surf, details, pkt_data, seek_ctx);
self.m_event->Record();
self.m_event->Wait();
if (res) {
self.m_event->Record();
self.m_event->Wait();
}
return std::make_tuple(res, details.m_info);
},
py::arg("surf"), py::arg("pkt_data"),
Expand All @@ -463,10 +469,11 @@ void Init_PyDecoder(py::module& m) {

auto res =
self.DecodeSingleSurface(surf, details, pkt_data, seek_ctx);
if (record_event) {
if (res && record_event) {
self.m_event->Record();
}
return std::make_tuple(res, details.m_info);
return std::make_tuple(res, details.m_info,
record_event ? self.m_event : nullptr);
},
py::arg("surf"), py::arg("pkt_data"), py::arg("record_event") = true,
py::arg("seek_ctx") = std::nullopt,
Expand Down
82 changes: 75 additions & 7 deletions tests/test_PyDecoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,54 @@ def test_timebase(self, device_name: str, device_id: int):
self.assertLessEqual(
np.abs(self.gtInfo.timebase - pyDec.Timebase), epsilon)

def test_dec_frame_cpu(self):
"""
This test checks that `DecodeSingleFrame` methods don't
work on GPU and return proper result.
"""
pyDec = vali.PyDecoder(self.gtInfo.uri, {}, gpu_id=0)

pkt_data = vali.PacketData()
frame = np.ndarray(dtype=np.uint8, shape=())

res, info = pyDec.DecodeSingleFrame(frame)
self.assertFalse(res)
self.assertEqual(info, vali.TaskExecInfo.FAIL)

res, info = pyDec.DecodeSingleFrame(frame, pkt_data)
self.assertFalse(res)
self.assertEqual(info, vali.TaskExecInfo.FAIL)

def test_dec_surface_cpu(self):
"""
This test checks that `DecodeSingleSurface` methods don't
work on CPU and return proper result and event.
"""

pyDec = vali.PyDecoder(self.gtInfo.uri, {}, gpu_id=-1)

pkt_data = vali.PacketData()
surf = vali.Surface.Make(
pyDec.Format, pyDec.Width, pyDec.Height, gpu_id=0)

res, info = pyDec.DecodeSingleSurface(surf)
self.assertFalse(res)
self.assertEqual(info, vali.TaskExecInfo.FAIL)

res, info = pyDec.DecodeSingleSurface(surf, pkt_data)
self.assertFalse(res)
self.assertEqual(info, vali.TaskExecInfo.FAIL)

res, info, evt = pyDec.DecodeSingleSurfaceAsync(surf)
self.assertFalse(res)
self.assertEqual(info, vali.TaskExecInfo.FAIL)
self.assertIsNone(evt)

res, info, evt = pyDec.DecodeSingleSurfaceAsync(surf, pkt_data)
self.assertFalse(res)
self.assertEqual(info, vali.TaskExecInfo.FAIL)
self.assertIsNone(evt)

@parameterized.expand([
["from_url"],
["from_buf"]
Expand Down Expand Up @@ -308,7 +356,7 @@ def test_check_all_frames_cpu(self, input_type):
dec_frames += 1

self.assertEqual(self.yuvInfo.num_frames, dec_frames)

if buf is not None:
buf.close()

Expand Down Expand Up @@ -352,11 +400,26 @@ def test_monotonous_pts_increase_gpu(self, case_name: str):
lastPts = pktData.pts

@parameterized.expand([
["avc_8bit", "basic", "basic_nv12"],
["hevc_10bit", "hevc10", "hevc10_p10"],
[True, "avc_8bit", "basic", "basic_nv12"],
[False, "avc_8bit", "basic", "basic_nv12"],
[True, "hevc_10bit", "hevc10", "hevc10_p10"],
[False, "hevc_10bit", "hevc10", "hevc10_p10"],
])
def test_check_all_surfaces_gpu(self, case_name: str, gt_comp_name: str,
gt_raw_name: str):
def test_check_all_surfaces_gpu(
self,
is_async: bool,
case_name: str,
gt_comp_name: str,
gt_raw_name: str):
"""
This test checks decoded surfaces pixel-by-pixel.

Args:
is_async (bool): if True, will run async non-blocking api, otherwise sync blocking api
case_name (str): test case name
gt_comp_name (str): ground truth information about compressed file
gt_raw_name (str): ground truth information about raw file
"""

gt_comp = self.gtByName(gt_comp_name)
gt_raw = self.gtByName(gt_raw_name)
Expand All @@ -371,8 +434,13 @@ def test_check_all_surfaces_gpu(self, case_name: str, gt_comp_name: str,
pyDec.Format, pyDec.Width, pyDec.Height, gpu_id=0)
frame = np.ndarray(dtype=np.uint8, shape=surf.HostSize)

# Decode single surface from file
success, details = pyDec.DecodeSingleSurface(surf)
# Decode single surface
if is_async:
success, details, _ = pyDec.DecodeSingleSurfaceAsync(
surf, False)
else:
success, details = pyDec.DecodeSingleSurface(surf)

if not success:
self.log.info('decode: ' + str(details))
break
Expand Down
Loading