Skip to content

Build packet decoders from decoder parameters - #1780

Draft
NicolasHug wants to merge 1 commit into
packet-decoder-parameters-cppfrom
decoder-parameters
Draft

NicolasHug wants to merge 1 commit into
packet-decoder-parameters-cppfrom
decoder-parameters

Conversation

@NicolasHug

@NicolasHug NicolasHug commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

This is part of a stack that adds demuxer-free decoding to the low-level APIs: decoding packets that don't come from a Demuxer (#1585), demuxing and decoding in different processes, and raw H.264 / HEVC streams (#1771).


VideoPacketDecoder and AudioPacketDecoder can now be built directly from the decoder parameters added in #1779, whether they come from a stream or are built by hand:

# From a demuxer (this is what stream.make_decoder() now does):
decoder = VideoPacketDecoder(demuxer.streams[0].decoder_parameters, device="cuda")

# Or by hand, for packets that don't come from a demuxer:
params = VideoPacketDecoderParameters("h264", time_base=(1, 90000), extradata=avcc)
decoder = VideoPacketDecoder(params, device="cuda", decoder="h264")
  • One construction path: stream.make_decoder() goes through the same path, so a demuxed stream and its parameters can't decode differently.
  • decoder= selects a specific FFmpeg decoder, which must decode the parameters' codec.
  • Validation: unknown codecs, enum names or fields raise when the decoder is built. framerate needs FFmpeg 6 and coded_side_data needs FFmpeg 6.1; setting them on older versions raises.

C++ changes worth a look

  • No more Demuxer in PacketDecoder: it's built from DecoderParameters.
  • Breaking for out-of-tree device interfaces: DeviceInterface::initialize_video_decoding() (and initialize_video()) take the DecoderParameters instead of an AVStream and an AVFormatContext, so out-of-tree interfaces that override it need updating. The in-tree third-party interface test doesn't override it. SingleStreamDecoder builds its DecoderParameters from its stream with the same get_decoder_parameters() as the Demuxer path.
  • NVDEC bitstream filter: it used to be picked from the container name, and there may not be a container anymore. h264_mp4toannexb / hevc_mp4toannexb are now applied when the extradata isn't Annex B, using the same check as the filters themselves: Annex B extradata is empty or starts with a start code.
    • That's equivalent to the old container check for every container we handled: avcC / hvcC extradata gets the filter, and Annex B extradata didn't need it, since the filters pass Annex B through.
    • It also covers hvcC with a configurationVersion of 0, which early HEVC muxers wrote, and length-prefixed H.264 in AVI, which used to get no filter.
  • MPEG-4 on NVDEC: mpeg4_unpack_bframes is now applied to every MPEG-4 stream, not just AVI ones. It passes any packet that isn't DivX-packed through unchanged.

Part of #1585.

Tests

  • Parameters rebuilt from their public fields decode exactly like the originals: H.264, HEVC, AV1, VP9, MPEG-4, a rotated video, AAC, MP3, PCM. CPU and CUDA.
  • Hand-built parameters work: avcC H.264 with extradata, Annex B H.264 with only codec and time_base, PCM. CPU and CUDA. The CUDA cases go through the extradata-based filter choice.
  • Validation errors and decoder=.

Stack created with GitHub Stacks CLI • Give Feedback 💬

@pytorch-bot

pytorch-bot Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/meta-pytorch/torchcodec/1780

Note: Links to docs will display an error until the docs builds have been completed.

❌ 11 New Failures, 8 Unrelated Failures

As of commit 2141766 with merge base ffb098a (image):

NEW FAILURES - The following jobs have failed:

FLAKY - The following jobs failed but were likely due to flakiness present on trunk:

BROKEN TRUNK - The following jobs failed but were present on the merge base:

👉 Rebase onto the `viable/strict` branch to avoid these failures

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@NicolasHug
NicolasHug added this pull request to stack #1784 October 27, 2026 13:04
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Oct 27, 2026
@NicolasHug
NicolasHug force-pushed the decoder-parameters branch 2 times, most recently from 21b0e2f to b6b975a Compare October 27, 2026 13:44
@NicolasHug
NicolasHug force-pushed the decoder-parameters branch 2 times, most recently from 92b7200 to f1c02a9 Compare October 27, 2026 16:32
VideoPacketDecoder(parameters, device, *, num_ffmpeg_threads, decoder)
and AudioPacketDecoder(parameters, *, decoder) can now be built
directly from VideoPacketDecoderParameters / AudioPacketDecoderParameters,
whether they come from a stream or are built by hand. stream.make_decoder()
goes through the same path, so a demuxed stream and its parameters can't
decode differently. decoder= selects a specific FFmpeg decoder. Invalid
parameters (unknown codec, enum name or field) raise when building the
decoder.

On the C++ side, PacketDecoder is now built from DecoderParameters
instead of a Demuxer, and so is the device interface:
DeviceInterface::initialize_video_decoding() takes DecoderParameters
instead of an AVStream and AVFormatContext. This breaks out-of-tree
device interfaces that override it.

Since there may not be a container anymore, NVDEC no longer picks its
bitstream filter from the container name: the mp4toannexb filters are
applied when the extradata isn't Annex B, the same check those filters
make, and mpeg4_unpack_bframes is applied to every MPEG-4 stream (it
passes through packets that aren't packed).

Part of #1585.
@NicolasHug NicolasHug changed the title Add VideoPacketDecoderParameters and AudioPacketDecoderParameters Build packet decoders from decoder parameters Oct 27, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant