Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add validateAndAdjustResourceDurations method for Imperor #383

Closed
wants to merge 1 commit into from

Conversation

AllMethodGrind
Copy link
Contributor

No description provided.

long remainder = 0;

if (resourceEditRateDenominator == 1001) {
// Non-integer frame rates must be evenly divisible by 5 in order to align with audio samples
Copy link
Contributor

Choose a reason for hiding this comment

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

Unfortunately, the math gets more complicated than this.

The issue isn't entirely related to non-integer rates. But instead, it is caused when the rates of two tracks are not multiples with one another, such that each video frame ends exactly on the bounds of an audio sample.

That means that both the video AND audio rate are relevant. Luckily, the IMF core constraints limit the audio sample rate to only a few rates that are easy to work with (2067-2:2020 5.3.2.2). So really, we only need to worry about the video frame rate.

Most of the common non-integer video frame rates actually are compatible with the allowed audio sample rates. 24000/1001 fps to 48kHz works out to be exactly 2002 samples-per-frame.
The only common frame rates that are really problematic are 30000/1001 and 60000/1001. Thats where you end up needing to align on every fifth video frame.

But this check should still allow non-integer frame rates for 23.976 and 47.952

long totalResourceDuration = resources.stream()
.mapToLong(resource -> {
if (resource != null) {
return resource.getSourceDuration().longValue();
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe you should use resource.getDuration() instead of getSourceDuration().
Although it is pretty uncommon, it is possible for a Resource to set a 'repeatCount'. The getDuration method will include the total for all repeats.

@davidt-netflix
Copy link
Contributor

Maybe it would be better if, rather than automatically adjusting the duration of the last Resource, you were to simply return an error, or throw an Exception? That would allow/require the caller to make decisions about how they want to fix the timeline they provided.

For your specific business case, what you wrote makes sense. You are always willing to drop the last few units to make things line up.
But that isn't the only option for fixing these mismatches. Maybe in some scenarios, it makes more sense to cut a few units from the beginning of the timeline. Or even, to shorten an element somewhere in the middle. As long as all of the Sequences have the same duration, it is valid.

We shouldn't presume that making cuts to the end is always best. Since Photon is intended to be an open source, general purpose IMF tool, it is always good to try to avoid letting our own business logic dictate the "default" behavior for non-Netflix users.


// Validate and adjust the durations of the resources in the track
List<IMFTrackFileResourceType> adjustedResources = SequenceDurationValidator.validateAndAdjustResourceDurations(resources, simpleTimeline.getEditRate().getNumerator(), simpleTimeline.getEditRate().getDenominator());

Copy link
Contributor

Choose a reason for hiding this comment

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

It might be worth considering performing the duration validation on "all tracks" together, rather than on "all Resources within one track". So maybe after the virtualTracks list has been populated, but before the buildIMP call.

One advantage of this, is that it would catch other kinds of track duration mismatches also. Not just fractional edit units due to EditRate mismatches, but it would also be able to catch a lot of user-error, from the provided timeline.
As far as I can tell, SimpleTimeline doesn't have any sort of track duration validation. So it would be possible for the caller to (mistakenly) provide a video track with duration 30 seconds, and an audio track with duration 35 seconds.

This isn't a high priority, and is outside the scope of the problem you are currently try to address. But if you end up needing to shuffle any of this logic around anyway, then it might make sense to just handle both cases in an all-purpose track-duration-validator.

editRate,
lastResource.getIntrinsicDuration(),
lastResource.getEntryPoint(),
BigInteger.valueOf(lastResource.getSourceDuration().longValue() - remainder),
Copy link
Contributor

Choose a reason for hiding this comment

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

Be careful with adjusting the sourceDuration, without first checking if repeatCount > 1.

I don't think it will impact your specific use-case. But for other users, in the unlikely event that the last Resource in the track uses repeats, then your adjustment will decrease the duration of each loop.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants