From 64231ee079e361477596c61956ae8b78f77ac020 Mon Sep 17 00:00:00 2001 From: ibaker Date: Fri, 22 Dec 2023 08:03:49 -0800 Subject: [PATCH] Tweak `SubtitleTranscodingTrackOutput.ensureSampleDataCapacity` This more closely matches the intended, documented behaviour of this method. The previous implementation was incorrectly checking `sampleDataEnd + newSampleSize`, but it's more correct to compare `existingSampleDataLength + newSampleSize`, in order to handle the case of non-zero `sampleDataStart`. We've already checked above whether `newSampleSize` fits after `sampleDataEnd` without growing or reshuffling the array, so no need to basically repeat that check. In the case of handling one sample at a time, the previous implementation resulted in `sampleData` growing by `sampleSize` **every time** the pointers reached the end. With the new check for `sampleDataStart == sampleDataEnd`, this is avoided by always writing each new sample at the start of the array (because the previous sample has already been consumed), meaning `sampleData` remains equal to `sampleSize` without growing. PiperOrigin-RevId: 593119927 --- .../text/SubtitleTranscodingTrackOutput.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/text/SubtitleTranscodingTrackOutput.java b/libraries/extractor/src/main/java/androidx/media3/extractor/text/SubtitleTranscodingTrackOutput.java index eb797e8f90..a61d274a5c 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/text/SubtitleTranscodingTrackOutput.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/text/SubtitleTranscodingTrackOutput.java @@ -20,7 +20,6 @@ import static androidx.media3.common.util.Assertions.checkArgument; import static androidx.media3.common.util.Assertions.checkNotNull; import static androidx.media3.common.util.Assertions.checkState; import static androidx.media3.common.util.Assertions.checkStateNotNull; -import static java.lang.Math.max; import androidx.annotation.Nullable; import androidx.media3.common.C; @@ -151,6 +150,11 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; SubtitleParser.OutputOptions.allCues(), cuesWithTiming -> outputSample(cuesWithTiming, timeUs, flags)); sampleDataStart = sampleStart + size; + if (sampleDataStart == sampleDataEnd) { + // The array is now empty, so we can move the start and end pointers back to the start. + sampleDataStart = 0; + sampleDataEnd = 0; + } } // Clearing deprecated decode-only flag for compatibility with decoders that are still using it. @@ -194,7 +198,10 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; return; } int existingSampleDataLength = sampleDataEnd - sampleDataStart; - int targetLength = max(existingSampleDataLength * 2, sampleDataEnd + newSampleSize); + // Make sure there's enough space for the new sample (after we move existing data to the + // beginning of the array). + int targetLength = + Math.max(existingSampleDataLength * 2, existingSampleDataLength + newSampleSize); byte[] newSampleData = targetLength <= sampleData.length ? sampleData : new byte[targetLength]; System.arraycopy(sampleData, sampleDataStart, newSampleData, 0, existingSampleDataLength); sampleDataStart = 0;