Skip to content

Commit 1b52c93

Browse files
committed
Use parserParams.pExtVideoInfo instead of a BSF
1 parent cab333b commit 1b52c93

4 files changed

Lines changed: 17 additions & 12 deletions

File tree

src/torchcodec/_core/BetaCudaDeviceInterface.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,21 @@ void BetaCudaDeviceInterface::initialize(
339339
parserParams.pfnDecodePicture = pfnDecodePictureCallback;
340340
parserParams.pfnDisplayPicture = pfnDisplayPictureCallback;
341341

342+
// Some containers (e.g. MP4/MOV) store codec config (H.264 SPS/PPS,
343+
// MPEG-4 VOS/VOL, etc.) in extradata rather than inline in the
344+
// bitstream. The NVCUVID parser needs this data to initialize, so we
345+
// pass it via pExtVideoInfo. Same approach as DALI and FFmpeg cuviddec.
346+
// DALI does the same thing
347+
// https://github.com/NVIDIA/DALI/blob/ae79f316ae9b14c464d9cb98465f7f783da9ea89/dali/operators/video/frames_decoder_gpu.cc#L402-L408
348+
if (codecPar->extradata_size > 0) {
349+
auto seqhdrSize = std::min(
350+
static_cast<size_t>(codecPar->extradata_size),
351+
sizeof(parserExtInfo_.raw_seqhdr_data));
352+
parserExtInfo_.format.seqhdr_data_length = seqhdrSize;
353+
memcpy(parserExtInfo_.raw_seqhdr_data, codecPar->extradata, seqhdrSize);
354+
parserParams.pExtVideoInfo = &parserExtInfo_;
355+
}
356+
342357
CUresult result = cuvidCreateVideoParser(&videoParser_, &parserParams);
343358
STD_TORCH_CHECK(
344359
result == CUDA_SUCCESS, "Failed to create video parser: ", result);
@@ -390,12 +405,6 @@ void BetaCudaDeviceInterface::initializeBSF(
390405
avFormatCtx->iformat->name ? avFormatCtx->iformat->name : "";
391406
if (formatName == "avi") {
392407
filterName = "mpeg4_unpack_bframes";
393-
} else {
394-
// For MPEG-4 Part 2 in MP4/MOV/etc., codec configuration (VOS/VOL)
395-
// lives only in extradata. Unlike H.264/HEVC there's no codec-specific
396-
// BSF that injects it inline, so use dump_extra to prepend extradata
397-
// to keyframe packets — the NVCUVID parser needs this to initialize.
398-
filterName = "dump_extra";
399408
}
400409
break;
401410
}

src/torchcodec/_core/BetaCudaDeviceInterface.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ class BetaCudaDeviceInterface : public DeviceInterface {
8989
CUvideoparser videoParser_ = nullptr;
9090
UniqueCUvideodecoder decoder_;
9191
CUVIDEOFORMAT videoFormat_ = {};
92+
CUVIDEOFORMATEX parserExtInfo_ = {};
9293

9394
std::queue<CUVIDPARSERDISPINFO> readyFrames_;
9495

test/test_decoders.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1980,9 +1980,7 @@ def test_default_cuda_interface_backwards(self, asset, seek_mode):
19801980
@pytest.mark.parametrize("seek_mode", ("exact", "approximate"))
19811981
def test_cuda_mpeg4_mp4_first_frame(self, seek_mode):
19821982
# non-regression test for
1983-
# https://github.com/meta-pytorch/torchcodec/issues/1340. MPEG-4 Part 2
1984-
# in MP4 stores codec config (VOS/VOL) only in extradata, never inline.
1985-
# Without the dump_extra BSF, the NVCUVID parser could not initialize.
1983+
# https://github.com/meta-pytorch/torchcodec/issues/1340.
19861984
decoder = VideoDecoder(
19871985
TEST_SRC_2_MPEG4_MP4.path, device="cuda", seek_mode=seek_mode
19881986
)

test/utils.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -729,9 +729,6 @@ def get_empty_chw_tensor(self, *, stream_index: int) -> torch.Tensor:
729729
)
730730

731731
# ffmpeg -f lavfi -i color=c=black:s=64x64:d=0.034 -c:v mpeg4 -q:v 31 testsrc2_mpeg4.mp4
732-
# MPEG-4 Part 2 in MP4 stores codec config (VOS/VOL) in extradata only, with
733-
# no inline copies in the bitstream — exercises the dump_extra BSF path on
734-
# the default CUDA backend.
735732
TEST_SRC_2_MPEG4_MP4 = TestVideo(
736733
filename="testsrc2_mpeg4.mp4",
737734
default_stream_index=0,

0 commit comments

Comments
 (0)