Skip to content

Let the C++ Demuxer follow several streams of one container - #1677

Merged
NicolasHug merged 1 commit into
mainfrom
msd/cpp-multi-stream
Sep 3, 2026
Merged

Let the C++ Demuxer follow several streams of one container#1677
NicolasHug merged 1 commit into
mainfrom
msd/cpp-multi-stream

Conversation

@NicolasHug

@NicolasHug NicolasHug commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

The demuxer selected exactly one stream at construction. It now opens and probes in the constructor, and follows streams through add_stream(), which can be called more than once; av_read_frame's output is filtered against the set, and each packet is handed back with the stream index it came from.

seek() takes the stream to resolve against, since FFmpeg resolves a seek in one stream's time base and lands on that stream's keyframes: it's stream-dependent. By default, it picks the first followed stream as passed by the streams= parameter at Demuxer creation.

No Python API changes.

Stack created with GitHub Stacks CLIGive Feedback 💬

@pytorch-bot

pytorch-bot Bot commented Sep 1, 2026

Copy link
Copy Markdown

🔗 Helpful Links

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

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

⏳ No Failures, 18 Pending

As of commit 30fed89 with merge base 0d3103d (image):
💚 Looks good so far! There are no failures yet. 💚

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

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Sep 1, 2026
@NicolasHug
NicolasHug force-pushed the msd/cpp-multi-stream branch 3 times, most recently from 0a7fce7 to 03bd3e2 Compare September 2, 2026 12:52
@NicolasHug
NicolasHug changed the base branch from msd/eof-sentinels to msd/frame-index-rename September 2, 2026 12:56
Base automatically changed from msd/frame-index-rename to main September 2, 2026 13:51
Comment on lines +52 to +60
int read_next_packet(
AVFormatContext* format_context,
int active_stream_index,
ReferenceAVPacket& packet) {
return read_next_active_packet(
format_context, packet, [active_stream_index](int stream_index) {
return stream_index == active_stream_index;
});
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this one can be removed when addressing the PR just above (scan)

The demuxer selected exactly one stream at construction. It now opens and
probes in the constructor, and follows streams through add_stream(), which
can be called more than once; av_read_frame's output is filtered against the
set, and each packet is handed back with the stream index it came from.

This is what makes audio + video from one container a single pass. Two
single-stream demuxers open the file twice, and a source that is expensive
to open twice pays for it.

seek() takes the stream to resolve against, since FFmpeg resolves a seek in
one stream's time base and lands on that stream's keyframes; left
unspecified it picks the first followed video stream, then the first
followed stream. scan() likewise takes the stream to index. PacketDecoder
takes the stream it decodes rather than reading the demuxer's only one.

No Python API changes: VideoDemuxer and AudioDemuxer construct then add
their single stream, and behave exactly as before. Adding a stream once
demuxing has started is rejected - it would start from wherever the
container currently is rather than from the beginning.
@NicolasHug
NicolasHug merged commit ba6b3f7 into main Sep 3, 2026
33 checks passed
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