Skip to content

Commit f37f969

Browse files
icbakercopybara-github
authored andcommitted
Pass missing length into SubtitleParser from SubtitleExtractor
If the length of the `ExtractorInput` is not known then the `subtitleData` field is re-sized by 1kB each time (`SubtitleExtractor.DEFAULT_BUFFER_SIZE`), so the end of the array is often not populated. This change ensures that `length` is propagated to `SubtitleParser`, so that implementations don't try and parse the garbage/zero bytes at the end of the array. Discovered while investigating Issue: androidx/media#1516 #cherrypick PiperOrigin-RevId: 661195634
1 parent 8b33ad5 commit f37f969

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

libraries/extractor/src/main/java/androidx/media3/extractor/text/SubtitleExtractor.java

+2
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,8 @@ private void parseAndWriteToOutput() throws IOException {
237237
: SubtitleParser.OutputOptions.allCues();
238238
subtitleParser.parse(
239239
subtitleData,
240+
/* offset= */ 0,
241+
/* length= */ bytesRead,
240242
outputOptions,
241243
cuesWithTiming -> {
242244
Sample sample =

libraries/extractor/src/test/java/androidx/media3/extractor/text/SubtitleExtractorTest.java

+41
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import androidx.media3.common.Format;
2222
import androidx.media3.common.MimeTypes;
23+
import androidx.media3.common.util.Consumer;
2324
import androidx.media3.common.util.Util;
2425
import androidx.media3.extractor.Extractor;
2526
import androidx.media3.extractor.text.webvtt.WebvttParser;
@@ -28,6 +29,7 @@
2829
import androidx.media3.test.utils.FakeTrackOutput;
2930
import androidx.test.ext.junit.runners.AndroidJUnit4;
3031
import com.google.common.primitives.Ints;
32+
import java.util.concurrent.atomic.AtomicInteger;
3133
import org.junit.Before;
3234
import org.junit.Test;
3335
import org.junit.runner.RunWith;
@@ -188,6 +190,45 @@ public void extractor_seekBetweenReads_outputsCues() throws Exception {
188190
assertThat(cues2.cues.get(0).text.toString()).isEqualTo("This is the third subtitle.");
189191
}
190192

193+
@Test
194+
public void extractor_unknownLengthInput_passesNumberOfBytesReadToSubtitleParser()
195+
throws Exception {
196+
FakeExtractorOutput output = new FakeExtractorOutput();
197+
byte[] inputData = Util.getUtf8Bytes(TEST_DATA);
198+
FakeExtractorInput input =
199+
new FakeExtractorInput.Builder()
200+
.setData(inputData)
201+
.setSimulatePartialReads(true)
202+
.setSimulateUnknownLength(true)
203+
.build();
204+
AtomicInteger lengthFromParse = new AtomicInteger();
205+
SubtitleParser fakeSubtitleParser =
206+
new SubtitleParser() {
207+
@Override
208+
public void parse(
209+
byte[] data,
210+
int offset,
211+
int length,
212+
OutputOptions outputOptions,
213+
Consumer<CuesWithTiming> output) {
214+
lengthFromParse.set(length);
215+
}
216+
217+
@Override
218+
public @Format.CueReplacementBehavior int getCueReplacementBehavior() {
219+
return Format.CUE_REPLACEMENT_BEHAVIOR_MERGE;
220+
}
221+
};
222+
SubtitleExtractor extractor =
223+
new SubtitleExtractor(
224+
fakeSubtitleParser, new Format.Builder().setSampleMimeType(MimeTypes.TEXT_VTT).build());
225+
226+
extractor.init(output);
227+
while (extractor.read(input, null) != Extractor.RESULT_END_OF_INPUT) {}
228+
229+
assertThat(lengthFromParse.get()).isEqualTo(inputData.length);
230+
}
231+
191232
@Test
192233
public void read_withoutInit_fails() {
193234
FakeExtractorInput input = new FakeExtractorInput.Builder().setData(new byte[0]).build();

0 commit comments

Comments
 (0)