From 0358d643cf1cdff738775a64a83ddf7cd8b4255b Mon Sep 17 00:00:00 2001 From: pinjie Date: Wed, 20 May 2026 02:18:52 -0700 Subject: [PATCH] feat: support SPS extradata parser when demuxer Signed-off-by: pinjie --- .../pix_fmt_variants/h264_avc1_yuv420p.mp4 | Bin 0 -> 17556 bytes .../pix_fmt_variants/hevc_hev1_yuv420p.mp4 | Bin 0 -> 23326 bytes .../hevc_hev1_yuv420p10le.mp4 | Bin 0 -> 19782 bytes .../pix_fmt_variants/hevc_hvc1_yuv420p.mp4 | Bin 0 -> 23326 bytes .../hevc_hvc1_yuv420p10le.mp4 | Bin 0 -> 19782 bytes .../helper_classes/Utils/FFmpegDemuxer.h | 269 ++++++++++++++++++ .../tests/test_pix_fmt_detection.py | 120 ++++++++ .../on_demand_video_decoder/tests/utils.py | 9 +- 8 files changed, 397 insertions(+), 1 deletion(-) create mode 100644 packages/on_demand_video_decoder/data/pix_fmt_variants/h264_avc1_yuv420p.mp4 create mode 100644 packages/on_demand_video_decoder/data/pix_fmt_variants/hevc_hev1_yuv420p.mp4 create mode 100644 packages/on_demand_video_decoder/data/pix_fmt_variants/hevc_hev1_yuv420p10le.mp4 create mode 100644 packages/on_demand_video_decoder/data/pix_fmt_variants/hevc_hvc1_yuv420p.mp4 create mode 100644 packages/on_demand_video_decoder/data/pix_fmt_variants/hevc_hvc1_yuv420p10le.mp4 create mode 100644 packages/on_demand_video_decoder/tests/test_pix_fmt_detection.py diff --git a/packages/on_demand_video_decoder/data/pix_fmt_variants/h264_avc1_yuv420p.mp4 b/packages/on_demand_video_decoder/data/pix_fmt_variants/h264_avc1_yuv420p.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..7ca9653927a0a9b6eed3e2aa43d2e5791de2e66c GIT binary patch literal 17556 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
    0ACxlXsD&wkQY{0eY=P{>%%%~g)4x- z872xQHTHD0cELh;N{+6%%K#L^Tjn#ce*W6hdOxzLSMp0*^~cSzW}iS6X^qI2c{{d4p)C4h4e6M^vWWYXG>0i(ZwT?8y4Y&I z&;JG1<=*GcxSg@dGg4Sn7xbzO@_h8Fnw;lDefate`eF_#b?6;&4HgqaHBWFiCHty{IZN z`=1ue@HA3fe~i2f$5qm+XwOF{!o|wxlJ;m(iLyGC(X#6RC`d?^U+c*}1B!!`6xnn? z-o5zYbBQl`qR=b>)SzKgvfF5zpBRJ+?fS$-`F)o+kryzCzW&fD3U_Tplgw#W17m@eP-cj7~xB;pyRNN0ScXF!FFlF8!zW5`mG%kr*#xCZg(&pDt z33i~1Hx#8cpDAU0sbdigY!n4=#FQz`SK9~foOXN z5wV#~Q54@B^_ijXdi@zFhm`vMS{9v(vcEs@$XrwTg%z&}S4_a_9Qkp)BAKsG^ebKG zz^%`z#$_qSd&{3l?1_)&h?IWIFg~!^uec5@!Q+-*5;g3C7LTVM73DOI-_-T}lz#DO zzlMbRCt_wZ+h105Kbv#+1#Gy`uY;Gn9~}S`*v%n!)^@c|&ffeqsxZWGF%Qb+|9oML z=|8cRzCJXv>C(dpIbl8_+tY2&4Gc?S;yx6aJR8tUVKw|A0JUHqlV1vB7j*e8dWMz0 zhQCfQ{$c834^ue4i~Qyt#97%4sNJuWVn?l96E^r9I*rY$VSixO7O)%U`{VUz#%y8*8+ z4zd1xe?Edtf%H;XW1R!VskS)t5`F7$l0N}}Q$2bsjHRa7RnEk`{Mfll7)mAod@YQ5 zg%YfACB{DbIoG=dmKl}w7$Il;p+nL(vh$!0$tn2_Fm^%bXnt+sgYOLwltX6*0D_k! zr1!rEU>Ug4+`1b1Ft;`w$|1cYz5BKCW^1#Qx5Q9QZ0@8PTGwq27$orpf2`zAF{8QP zI%?uAH8tUk#+T29HY{z4&1!q^^QPq3*i?6d*l@^MM!zJvcfYUw!V6&V$CB$vCm$-bEJlgkJz{*b2%?lg}2V(+uilGoT)P=zl? z$dFbz_N%T?$+OPFF0I9QN`(^-4(!W|A9^p}z0SKs2lOD!>_Q}rsbr&$6|rEX-({=a zcnAQ50TU7jGp-k7XL3C>OD*`z>3R_jfxl1QCd;QV9M(#6{^dQ#Ov~4aT%0&%5@-+( zA(q42*Y^-8dwCynL*Fe~^G6BK^+cI4SV&dYl>T`Gz#kxd)nKje|9nk>!7vfvcNl2@ zIuPVZY7^~+tA8ujpxuA|{iB`#Rl7)KMNP=rDF{8Z<8}553|cV-5VA|PqQqF`?c`1b z4Cn3i&%SHG?~JT4dmBkLrQMvo0#M+GEf@gK{lWzSIa<$O?vv zpqwfiE-XO!K+tmp^mIudWHSiQia_>@!L3{y!Y9hd(6_REyNog z!W2MI8PY*~5Eo<{)mv>-d*vSKptf{Dkbmq!kd7t@s;3HqI3XQ$uM8ptg2oly+kzl& z=o;BtoeSt132GPhVYMA}9zx@b>a5m7<0}G!e29Fu4+OP=c%V6gxUKdP@z@4}xFS8o z4fPA*CLpLD;(}y#9Uwc%Z>Sv{$f_UEffm_Y?VAo7sE!*Qs} zKTw&*%01FS?b@u|ukt`RT8{`vg7_oe$R}uip*CSnP+;K``49O3jSs4ie4++|e1-af zFf_iX|L7C7kIE4)x^j=&Py#_5kqy+&>Ka1*LHDRnt2UATT3g8HvLL8@b=;6oP@8ff zYwaSwXzd^lNFVi+H89B07e3J+>JzHt5bP90gwOrn&ZJMc#0acCq{G2JfavGvg@DyR jX?OCI0O7(QUu2LE{x=b11R2G^Y1su%%lNHuT9*4CIFT(f literal 0 HcmV?d00001 diff --git a/packages/on_demand_video_decoder/data/pix_fmt_variants/hevc_hev1_yuv420p.mp4 b/packages/on_demand_video_decoder/data/pix_fmt_variants/hevc_hev1_yuv420p.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..3106626722ddf95c58d16444901a870e28dc9829 GIT binary patch literal 23326 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 literal 0 HcmV?d00001 diff --git a/packages/on_demand_video_decoder/data/pix_fmt_variants/hevc_hev1_yuv420p10le.mp4 b/packages/on_demand_video_decoder/data/pix_fmt_variants/hevc_hev1_yuv420p10le.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..aa1f9120544fd8bfcd90df3d5aa2f7b7b677a954 GIT binary patch literal 19782 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 Z5B?u$CiOYvup| literal 0 HcmV?d00001 diff --git a/packages/on_demand_video_decoder/data/pix_fmt_variants/hevc_hvc1_yuv420p.mp4 b/packages/on_demand_video_decoder/data/pix_fmt_variants/hevc_hvc1_yuv420p.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..993c116b162a92cf3494c57ae0bf5278d30bff8a GIT binary patch literal 23326 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 literal 0 HcmV?d00001 diff --git a/packages/on_demand_video_decoder/ext_impl/src/VideoCodecSDKUtils/helper_classes/Utils/FFmpegDemuxer.h b/packages/on_demand_video_decoder/ext_impl/src/VideoCodecSDKUtils/helper_classes/Utils/FFmpegDemuxer.h index e6b715e..534fe20 100644 --- a/packages/on_demand_video_decoder/ext_impl/src/VideoCodecSDKUtils/helper_classes/Utils/FFmpegDemuxer.h +++ b/packages/on_demand_video_decoder/ext_impl/src/VideoCodecSDKUtils/helper_classes/Utils/FFmpegDemuxer.h @@ -23,6 +23,7 @@ extern "C" { #include #include #include +#include /* Explicitly include bsf.h when building against FFmpeg 4.3 (libavcodec 58.45.100) or later for backward compatibility */ #if LIBAVCODEC_VERSION_INT >= 3824484 #include @@ -193,6 +194,259 @@ static int64_t ffbufio_seek(void* opaque, int64_t offset, int whence) { /** * @brief libavformat wrapper class. Retrieves the elementary encoded stream from the container format. */ +// ===================================================================== +// SPS extradata parser — fallback for pixel format detection +// --------------------------------------------------------------------- +// `avformat_find_stream_info` usually fills `AVCodecParameters::format` +// through codec-side parsing. In some builds, pixel format information +// may remain unavailable in `codecpar->format`, which can cause later +// logic to fall back to a default chroma layout. +// +// The helpers in this namespace parse the SPS NAL stored in container +// extradata (HVCC for HEVC, avcC for H.264) and extract the minimum +// fields needed to infer pixel format, specifically `bit_depth_luma` +// and `chroma_format_idc`. +// +// This is a lightweight metadata parser: it reads stream parameter +// fields only and is used for format detection rather than frame +// reconstruction. +// ===================================================================== +namespace ffmpeg_demuxer_detail { + +struct BitReader { + const uint8_t* buf; + int byte; + int bit; + int size; +}; + +inline int br_read_bit(BitReader* b) { + if (b->byte >= b->size) return 0; + int v = (b->buf[b->byte] >> (7 - b->bit)) & 1; + if (++b->bit == 8) { b->bit = 0; b->byte++; } + return v; +} + +inline unsigned br_read_bits(BitReader* b, int n) { + unsigned v = 0; + while (n-- > 0) { v = (v << 1) | (unsigned)br_read_bit(b); } + return v; +} + +inline unsigned br_read_ue(BitReader* b) { + int zeros = 0; + while (zeros < 32 && b->byte < b->size && br_read_bit(b) == 0) zeros++; + return (1u << zeros) - 1 + br_read_bits(b, zeros); +} + +// Strip H.264/HEVC emulation prevention bytes (0x00 0x00 0x03 -> 0x00 0x00). +inline int rbsp_strip(const uint8_t* src, int n, uint8_t* dst, int dst_capacity) { + int o = 0; + for (int i = 0; i < n && o < dst_capacity; i++) { + if (i + 2 < n && src[i] == 0 && src[i+1] == 0 && src[i+2] == 3) { + if (o + 2 > dst_capacity) break; + dst[o++] = 0; dst[o++] = 0; i += 2; + } else { + dst[o++] = src[i]; + } + } + return o; +} + +// Locate an SPS NAL inside HEVC HVCC extradata. +inline bool find_hevc_sps(const uint8_t* ed, int n, + const uint8_t** sps_out, int* sps_len_out) { + if (n < 23 || ed[0] != 1) return false; // configurationVersion=1 expected + int p = 22; + int num_arrays = ed[p++]; + for (int a = 0; a < num_arrays && p < n; a++) { + if (p + 3 > n) return false; + int nal_type = ed[p] & 0x3F; + int num_nalus = (ed[p+1] << 8) | ed[p+2]; + p += 3; + for (int i = 0; i < num_nalus; i++) { + if (p + 2 > n) return false; + int nl = (ed[p] << 8) | ed[p+1]; + p += 2; + if (p + nl > n) return false; + if (nal_type == 33 /* HEVC NAL_SPS */) { + *sps_out = ed + p; + *sps_len_out = nl; + return true; + } + p += nl; + } + } + return false; +} + +// Locate the first SPS NAL inside H.264 avcC extradata. +inline bool find_h264_sps(const uint8_t* ed, int n, + const uint8_t** sps_out, int* sps_len_out) { + if (n < 7 || ed[0] != 1) return false; // configurationVersion=1 + int num_sps = ed[5] & 0x1F; + if (num_sps < 1) return false; + int p = 6; + if (p + 2 > n) return false; + int nl = (ed[p] << 8) | ed[p+1]; + p += 2; + if (p + nl > n) return false; + *sps_out = ed + p; + *sps_len_out = nl; + return true; +} + +// Parse a HEVC SPS RBSP for chroma_format_idc and bit_depth_luma. +inline bool parse_hevc_sps(const uint8_t* sps_nal, int len, + int* bit_depth_out, int* chroma_idc_out) { + if (len < 3) return false; + uint8_t buf[8192]; + int copy_len = len > (int)sizeof(buf) ? (int)sizeof(buf) : len; + int rl = rbsp_strip(sps_nal, copy_len, buf, (int)sizeof(buf)); + BitReader b{ buf, 0, 0, rl }; + + br_read_bits(&b, 16); // 2-byte HEVC NAL header + br_read_bits(&b, 4); // sps_video_parameter_set_id + int max_sub = (int)br_read_bits(&b, 3); // sps_max_sub_layers_minus1 + br_read_bits(&b, 1); // sps_temporal_id_nesting_flag + + // profile_tier_level (profilePresentFlag = 1) + br_read_bits(&b, 2 + 1 + 5); // general_profile_space/tier/idc + br_read_bits(&b, 32); // general_profile_compatibility_flag + br_read_bits(&b, 4); // 4 source-format flags + br_read_bits(&b, 43); // constraint flags + br_read_bits(&b, 1); // general_inbld_flag + br_read_bits(&b, 8); // general_level_idc + + int sub_p[8] = {0}, sub_l[8] = {0}; + for (int i = 0; i < max_sub; i++) { + sub_p[i] = br_read_bit(&b); + sub_l[i] = br_read_bit(&b); + } + if (max_sub > 0) { + for (int i = max_sub; i < 8; i++) br_read_bits(&b, 2); + } + for (int i = 0; i < max_sub; i++) { + if (sub_p[i]) { + br_read_bits(&b, 2 + 1 + 5); + br_read_bits(&b, 32); + br_read_bits(&b, 4); + br_read_bits(&b, 43); + br_read_bits(&b, 1); + } + if (sub_l[i]) br_read_bits(&b, 8); + } + + br_read_ue(&b); // sps_seq_parameter_set_id + *chroma_idc_out = (int)br_read_ue(&b); + if (*chroma_idc_out == 3) br_read_bit(&b); // separate_colour_plane_flag + br_read_ue(&b); // pic_width_in_luma_samples + br_read_ue(&b); // pic_height_in_luma_samples + if (br_read_bit(&b)) { // conformance_window_flag + br_read_ue(&b); br_read_ue(&b); + br_read_ue(&b); br_read_ue(&b); + } + *bit_depth_out = 8 + (int)br_read_ue(&b); + return true; +} + +// Parse an H.264 SPS RBSP. Baseline / Main profiles imply 4:2:0 8-bit. +inline bool parse_h264_sps(const uint8_t* sps_nal, int len, + int* bit_depth_out, int* chroma_idc_out) { + if (len < 4) return false; + uint8_t buf[4096]; + int copy_len = len > (int)sizeof(buf) ? (int)sizeof(buf) : len; + int rl = rbsp_strip(sps_nal, copy_len, buf, (int)sizeof(buf)); + BitReader b{ buf, 0, 0, rl }; + + br_read_bits(&b, 8); // 1-byte H.264 NAL header + int profile_idc = (int)br_read_bits(&b, 8); + br_read_bits(&b, 8); // constraint_set + reserved + br_read_bits(&b, 8); // level_idc + br_read_ue(&b); // seq_parameter_set_id + + // Only the high profiles carry chroma_format_idc / bit_depth fields. + // ITU-T H.264 (V14) 7.4.2.1.1. + static const int hi_profiles[] = { + 100, 110, 122, 244, 44, 83, 86, 118, 128, 138, 139, 134, 135 + }; + bool is_high = false; + for (size_t i = 0; i < sizeof(hi_profiles) / sizeof(hi_profiles[0]); i++) { + if (profile_idc == hi_profiles[i]) { is_high = true; break; } + } + if (!is_high) { + *chroma_idc_out = 1; // implied 4:2:0 + *bit_depth_out = 8; // implied 8-bit + return true; + } + + *chroma_idc_out = (int)br_read_ue(&b); + if (*chroma_idc_out == 3) br_read_bit(&b); // separate_colour_plane_flag + *bit_depth_out = 8 + (int)br_read_ue(&b); + return true; +} + +// Map (chroma_format_idc, bit_depth) to the AVPixelFormat enum values the +// existing eChromaFormat switch handles. Returns AV_PIX_FMT_NONE for +// combinations we do not synthesize; the existing default-branch fallback +// will then preserve current behavior. +inline AVPixelFormat pix_fmt_from_sps(int chroma_idc, int bit_depth) { + switch (chroma_idc) { + case 0: // monochrome + if (bit_depth == 8) return AV_PIX_FMT_GRAY8; + if (bit_depth == 10) return AV_PIX_FMT_GRAY10LE; + break; + case 1: // 4:2:0 + if (bit_depth == 8) return AV_PIX_FMT_YUV420P; + if (bit_depth == 10) return AV_PIX_FMT_YUV420P10LE; + if (bit_depth == 12) return AV_PIX_FMT_YUV420P12LE; + break; + case 3: // 4:4:4 + if (bit_depth == 8) return AV_PIX_FMT_YUV444P; + if (bit_depth == 10) return AV_PIX_FMT_YUV444P10LE; + if (bit_depth == 12) return AV_PIX_FMT_YUV444P12LE; + break; + default: + break; + } + return AV_PIX_FMT_NONE; +} + +// Top-level entry point. Returns AV_PIX_FMT_NONE when recovery is not +// possible (unsupported codec, missing extradata, malformed SPS, or an +// unmappable chroma/bit-depth combination). +inline AVPixelFormat recover_pix_fmt_from_extradata(const AVCodecParameters* cp) { + if (!cp || !cp->extradata || cp->extradata_size <= 0) { + return AV_PIX_FMT_NONE; + } + const uint8_t* sps = nullptr; + int sps_len = 0; + int bit_depth = 8; + int chroma_idc = 1; + + if (cp->codec_id == AV_CODEC_ID_HEVC) { + if (!find_hevc_sps(cp->extradata, cp->extradata_size, &sps, &sps_len)) { + return AV_PIX_FMT_NONE; + } + if (!parse_hevc_sps(sps, sps_len, &bit_depth, &chroma_idc)) { + return AV_PIX_FMT_NONE; + } + } else if (cp->codec_id == AV_CODEC_ID_H264) { + if (!find_h264_sps(cp->extradata, cp->extradata_size, &sps, &sps_len)) { + return AV_PIX_FMT_NONE; + } + if (!parse_h264_sps(sps, sps_len, &bit_depth, &chroma_idc)) { + return AV_PIX_FMT_NONE; + } + } else { + return AV_PIX_FMT_NONE; + } + + return pix_fmt_from_sps(chroma_idc, bit_depth); +} + +} // namespace ffmpeg_demuxer_detail + class FFmpegDemuxer { private: AVFormatContext* fmtc = NULL; @@ -329,6 +583,21 @@ class FFmpegDemuxer { eChromaFormat = (AVPixelFormat)fmtc->streams[iVideoStream]->codecpar->format; color_space = fmtc->streams[iVideoStream]->codecpar->color_space; color_range = fmtc->streams[iVideoStream]->codecpar->color_range; + + // FFmpeg builds without the HEVC / H.264 decoder cannot determine pix_fmt + // during stream-info probing. Fall back to parsing SPS extradata so the + // switch below sees the real format instead of taking the default branch. + if (eChromaFormat == AV_PIX_FMT_NONE) { + AVPixelFormat recovered = ffmpeg_demuxer_detail::recover_pix_fmt_from_extradata( + fmtc->streams[iVideoStream]->codecpar); + if (recovered != AV_PIX_FMT_NONE) { + const char* name = av_get_pix_fmt_name(recovered); + LOG(INFO) << "Recovered pix_fmt from SPS extradata: " + << (name ? name : "?"); + eChromaFormat = recovered; + } + } + switch (eChromaFormat) { case AV_PIX_FMT_YUV420P10LE: case AV_PIX_FMT_GRAY10LE: // monochrome is treated as 420 with chroma filled with 0x0 diff --git a/packages/on_demand_video_decoder/tests/test_pix_fmt_detection.py b/packages/on_demand_video_decoder/tests/test_pix_fmt_detection.py new file mode 100644 index 0000000..1b28ce8 --- /dev/null +++ b/packages/on_demand_video_decoder/tests/test_pix_fmt_detection.py @@ -0,0 +1,120 @@ +# Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# 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. + +""" +Pix_fmt detection coverage across the codec_tag / bit-depth matrix. + +Regression target: a previously-shipped patent-free FFmpeg build cannot populate +`AVCodecParameters::format` for HEVC / H.264 streams (no decoder is linked in to +probe the SPS), and the demuxer silently fell back to 8-bit yuv420p. For a real +10-bit HEVC stream this mis-sized the GPU output buffer by a factor of 2 and +crashed `DecodeFromGOP` with `CUDA_ERROR_INVALID_VALUE`. + +These tests drive `GetGOPList` + `DecodeFromGOP` over the matrix of stream +shapes the package supports on NVDEC (HEVC at both 8-bit and 10-bit with both +hev1 and hvc1 sample-entry tags, plus H.264 8-bit), and assert the decoded +planes carry the dtype implied by the stream's real bit-depth (uint8 for +8-bit, uint16 for 10-bit). This exercises the SPS-extradata fallback added to +FFmpegDemuxer.h when `codecpar->format == AV_PIX_FMT_NONE`. +""" + +import os +import pytest + +import accvlab.on_demand_video_decoder as nvc +import utils + +VARIANTS_DIR = os.path.join(utils.get_data_dir(), "pix_fmt_variants") + + +# Each variant lists the filename, the codec_tag carried by the container, the +# bit-depth the stream actually encodes, and the dtype that should appear on the +# decoded Y plane. All variants here are NVDEC-decodable on the GPUs this +# package targets — see the support matrix for codec/bit-depth coverage: +# https://developer.nvidia.com/video-encode-decode-support-matrix +VARIANTS = [ + ("hevc_hev1_yuv420p.mp4", "hev1", 8, "|u1"), + ("hevc_hev1_yuv420p10le.mp4", "hev1", 10, "|u2"), + ("hevc_hvc1_yuv420p.mp4", "hvc1", 8, "|u1"), + ("hevc_hvc1_yuv420p10le.mp4", "hvc1", 10, "|u2"), + ("h264_avc1_yuv420p.mp4", "avc1", 8, "|u1"), +] + + +def _video_path(name): + path = os.path.join(VARIANTS_DIR, name) + if not os.path.exists(path): + pytest.skip(f"test asset missing: {path}") + return path + + +@pytest.mark.parametrize( + "filename, codec_tag, bit_depth, expected_dtype", + VARIANTS, + ids=[v[0] for v in VARIANTS], +) +def test_decode_from_gop_round_trip(filename, codec_tag, bit_depth, expected_dtype): + """End-to-end: GetGOPList -> DecodeFromGOP must produce a plane of the + correct dtype for the stream's actual bit-depth.""" + path = _video_path(filename) + + demuxer = nvc.CreateGopDecoder(maxfiles=1, iGpu=0) + decoder = nvc.CreateGopDecoder(maxfiles=1, iGpu=0) + + gop_list = demuxer.GetGOPList([path], [0], useGOPCache=True) + assert gop_list, f"GetGOPList returned empty for {filename}" + gop_data, first_ids, gop_lens = gop_list[0] + assert gop_data.size > 0, f"GOP data is empty for {filename}" + assert first_ids == [0], f"unexpected first_ids={first_ids} for {filename}" + assert gop_lens and gop_lens[0] > 0, f"unexpected gop_lens={gop_lens} for {filename}" + + frames = decoder.DecodeFromGOP(gop_data, [path], [0]) + assert len(frames) == 1, f"expected 1 frame, got {len(frames)} for {filename}" + + planes = frames[0].cuda() + assert len(planes) >= 1, f"no planes returned for {filename}" + + cai = planes[0].__cuda_array_interface__ + assert cai["typestr"] == expected_dtype, ( + f"Y plane dtype mismatch for {filename}: got {cai['typestr']!r}, " + f"expected {expected_dtype!r} for {bit_depth}-bit" + ) + + expected_bytes_per_sample = 2 if bit_depth >= 10 else 1 + actual_bytes_per_sample = int(cai["typestr"][-1]) + assert actual_bytes_per_sample == expected_bytes_per_sample, ( + f"Y plane element size mismatch for {filename}: got " + f"{actual_bytes_per_sample}B, expected {expected_bytes_per_sample}B" + ) + + +@pytest.mark.parametrize( + "filename, codec_tag, bit_depth, expected_dtype", + VARIANTS, + ids=[v[0] for v in VARIANTS], +) +def test_decode_does_not_raise_invalid_value(filename, codec_tag, bit_depth, expected_dtype): + """Focused regression: the specific failure mode we fixed was + `CUDA_ERROR_INVALID_VALUE` thrown from DecodeFromGOP because the GPU buffer + was half the size NVDEC writes. Reproduce the exact call sequence the + customer used and assert it does not raise that error.""" + path = _video_path(filename) + demuxer = nvc.CreateGopDecoder(maxfiles=1, iGpu=0) + decoder = nvc.CreateGopDecoder(maxfiles=1, iGpu=0) + + gop_data, _, _ = demuxer.GetGOPList([path], [0], useGOPCache=True)[0] + # No prior RGB call to "prime" the GPU pool — exercise the raw YUV path + # directly, which was the broken path before the SPS fallback. + frames = decoder.DecodeFromGOP(gop_data, [path], [0]) + assert frames, f"DecodeFromGOP returned no frames for {filename}" diff --git a/packages/on_demand_video_decoder/tests/utils.py b/packages/on_demand_video_decoder/tests/utils.py index 22a37cf..6fc3730 100644 --- a/packages/on_demand_video_decoder/tests/utils.py +++ b/packages/on_demand_video_decoder/tests/utils.py @@ -141,7 +141,14 @@ def get_data_dir(): def select_random_clip(path_base): - subdirs = [d for d in os.listdir(path_base) if os.path.isdir(os.path.join(path_base, d))] + # Only consider sample_clip* subdirs as eligible for the general random-clip + # tests. Other data/ subdirs (e.g. pix_fmt_variants/) hold targeted fixtures + # whose contents may not be RGB-decodable on the runtime GPU. + subdirs = [ + d + for d in os.listdir(path_base) + if os.path.isdir(os.path.join(path_base, d)) and d.startswith("sample_clip") + ] if not subdirs: return None clip_dir = os.path.join(path_base, random.choice(subdirs))