MP4 edit lists: Use floor rather than ceil to find first sample

If the start time of the edit falls within a sample, start from that
sample rather than the next one. This ensures playback can start from
the correct point if the sample is a keyframe, rather than having to
start from the next one.

Issue: #7133
PiperOrigin-RevId: 302639115
This commit is contained in:
olly 2020-03-24 11:31:19 +00:00 committed by Oliver Woodman
parent c2e9c8e89a
commit eebe990d20

View File

@ -446,10 +446,15 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
long editDuration =
Util.scaleLargeTimestamp(
track.editListDurations[i], track.timescale, track.movieTimescale);
startIndices[i] = Util.binarySearchCeil(timestamps, editMediaTime, true, true);
startIndices[i] =
Util.binarySearchFloor(
timestamps, editMediaTime, /* inclusive= */ true, /* stayInBounds= */ true);
endIndices[i] =
Util.binarySearchCeil(
timestamps, editMediaTime + editDuration, omitClippedSample, false);
timestamps,
editMediaTime + editDuration,
/* inclusive= */ omitClippedSample,
/* stayInBounds= */ false);
while (startIndices[i] < endIndices[i]
&& (flags[startIndices[i]] & C.BUFFER_FLAG_KEY_FRAME) == 0) {
// Applying the edit correctly would require prerolling from the previous sync sample. In
@ -487,7 +492,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
long ptsUs = Util.scaleLargeTimestamp(pts, C.MICROS_PER_SECOND, track.movieTimescale);
long timeInSegmentUs =
Util.scaleLargeTimestamp(
timestamps[j] - editMediaTime, C.MICROS_PER_SECOND, track.timescale);
Math.max(0, timestamps[j] - editMediaTime), C.MICROS_PER_SECOND, track.timescale);
editedTimestamps[sampleIndex] = ptsUs + timeInSegmentUs;
if (copyMetadata && editedSizes[sampleIndex] > editedMaximumSize) {
editedMaximumSize = sizes[j];