Skip to content

Find muxer options in VideoEncoder to test fragmented mp4#1216

Open
Dan-Flores wants to merge 9 commits intometa-pytorch:mainfrom
Dan-Flores:fragmented_mp4_perhaps
Open

Find muxer options in VideoEncoder to test fragmented mp4#1216
Dan-Flores wants to merge 9 commits intometa-pytorch:mainfrom
Dan-Flores:fragmented_mp4_perhaps

Conversation

@Dan-Flores
Copy link
Contributor

@Dan-Flores Dan-Flores commented Feb 2, 2026

This PR adds logic to sortCodecOptions to find and set muxer options (check available options with ffmpeg -h muxer=mp4)

With these changes, we can now test that fragment related movflag options are utilized correctly.
But, without a 'streaming' video encoder, the benefits of fragmented mp4's are still not unlocked:

  • Fragmented MP4s are useful because they allow the video file to be consumed before it is closed.
  • However, since our encoder expects all frames to be encoded at once, the fragments are not flushed to become available to consume until the end of the encoding process, so we cannot access the video before encoding is completed.

@pytorch-bot
Copy link

pytorch-bot bot commented Feb 2, 2026

🔗 Helpful Links

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

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

❌ 1 New Failure

As of commit 50aae18 with merge base 6f10da0 (image):

NEW FAILURE - The following job has failed:

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 Feb 2, 2026
@Dan-Flores Dan-Flores marked this pull request as ready for review February 3, 2026 20:34
// https://github.com/FFmpeg/FFmpeg/blob/n8.0/libavformat/movenc.c#L8666
if (status > 0) {
status = AVSUCCESS;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Without this conversion, we interpret the positive returned integer as a random low level error unrelated to the encoding process (ex. 24 raises EMFILE: too many open files). It might just be a bug in the FFmpeg implementation that we can work around.

Since FFmpeg errors are negative, I think its fine to set the status to successful here.

Copy link
Contributor

@mollyxu mollyxu Feb 6, 2026

Choose a reason for hiding this comment

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

Thanks for providing context! Would we want to also add a comment on how ffmpeg errors are negative and link to source code?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated!

Copy link
Contributor

@NicolasHug NicolasHug left a comment

Choose a reason for hiding this comment

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

A few Qs and nits but LGTM, thanks @Dan-Flores

key.c_str(),
nullptr,
0,
AV_OPT_SEARCH_FAKE_OBJ,
Copy link
Contributor

Choose a reason for hiding this comment

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

Any reason not to use AV_OPT_SEARCH_CHILDREN here? It's used above for fmtOpt

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We only use AV_OPT_SEARCH_CHILDREN when an AVClass has children to iterate over.
I checked that the AVFormatContext class defines child_next and child_class_iterate to iterate through child fields:
https://github.com/FFmpeg/FFmpeg/blob/release/8.0/libavformat/options.c#L128-L137

While the muxer class for MOV does not define these functions:
https://github.com/FFmpeg/FFmpeg/blob/release/8.0/libavformat/movenc.c#L132-L137


@pytest.mark.skipif(
ffmpeg_major_version == 4,
reason="On FFmpeg 4 we error on truncated packets",
Copy link
Contributor

Choose a reason for hiding this comment

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

Where do we error? By "we" you mean TC, or FFmpeg (i.e. is this limitation enforced by us, or by FFmpeg)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a torchcodec limitation, I was able to decode the truncated video with FFmpeg 4. I'll update the reason message.

The error we get is Invalid data found when processing input, which means we are hitting AVERROR_INVALIDDATA (see errors), which we do not handle, we only check for AVERROR_EOF:

if (status == AVERROR_EOF) {
break;
}
STD_TORCH_CHECK(
status == AVSUCCESS,
"Failed to read frame from input file: ",
getFFMPEGErrorStringFromErrorCode(status));

Since this error only occurs on FFmpeg 4, I think it should be ok to leave as is.

assert len(truncated_decoder) >= 10
for i in range(10):
truncated_frame = truncated_decoder.get_frame_at(i)
assert torch.equal(truncated_frame.data, reference_frames[i].data)
Copy link
Contributor

Choose a reason for hiding this comment

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

Use torch.testing.assert_equal(..., rtol=0, atol=0), it provides better error messages than torch,equal.

# frag_duration creates fragments based on duration (in microseconds)
{"movflags": "+empty_moov", "frag_duration": "1000000"},
],
)
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a fun test!
Just to make sure, did you verify that it breaks if we don't pass the extra_option flags?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it fails to open the file when using extra_options={}:
RuntimeError: Could not open input file: .../fragmented_output.mp4 Invalid data found when processing input

Hopefully this fun test does not introduce flakiness!

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.

3 participants