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
This commit is contained in:
parent
8b33ad5811
commit
f37f9690f4
@ -237,6 +237,8 @@ public class SubtitleExtractor implements Extractor {
|
|||||||
: SubtitleParser.OutputOptions.allCues();
|
: SubtitleParser.OutputOptions.allCues();
|
||||||
subtitleParser.parse(
|
subtitleParser.parse(
|
||||||
subtitleData,
|
subtitleData,
|
||||||
|
/* offset= */ 0,
|
||||||
|
/* length= */ bytesRead,
|
||||||
outputOptions,
|
outputOptions,
|
||||||
cuesWithTiming -> {
|
cuesWithTiming -> {
|
||||||
Sample sample =
|
Sample sample =
|
||||||
|
@ -20,6 +20,7 @@ import static org.junit.Assert.assertThrows;
|
|||||||
|
|
||||||
import androidx.media3.common.Format;
|
import androidx.media3.common.Format;
|
||||||
import androidx.media3.common.MimeTypes;
|
import androidx.media3.common.MimeTypes;
|
||||||
|
import androidx.media3.common.util.Consumer;
|
||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
import androidx.media3.extractor.Extractor;
|
import androidx.media3.extractor.Extractor;
|
||||||
import androidx.media3.extractor.text.webvtt.WebvttParser;
|
import androidx.media3.extractor.text.webvtt.WebvttParser;
|
||||||
@ -28,6 +29,7 @@ import androidx.media3.test.utils.FakeExtractorOutput;
|
|||||||
import androidx.media3.test.utils.FakeTrackOutput;
|
import androidx.media3.test.utils.FakeTrackOutput;
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import com.google.common.primitives.Ints;
|
import com.google.common.primitives.Ints;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@ -188,6 +190,45 @@ public class SubtitleExtractorTest {
|
|||||||
assertThat(cues2.cues.get(0).text.toString()).isEqualTo("This is the third subtitle.");
|
assertThat(cues2.cues.get(0).text.toString()).isEqualTo("This is the third subtitle.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void extractor_unknownLengthInput_passesNumberOfBytesReadToSubtitleParser()
|
||||||
|
throws Exception {
|
||||||
|
FakeExtractorOutput output = new FakeExtractorOutput();
|
||||||
|
byte[] inputData = Util.getUtf8Bytes(TEST_DATA);
|
||||||
|
FakeExtractorInput input =
|
||||||
|
new FakeExtractorInput.Builder()
|
||||||
|
.setData(inputData)
|
||||||
|
.setSimulatePartialReads(true)
|
||||||
|
.setSimulateUnknownLength(true)
|
||||||
|
.build();
|
||||||
|
AtomicInteger lengthFromParse = new AtomicInteger();
|
||||||
|
SubtitleParser fakeSubtitleParser =
|
||||||
|
new SubtitleParser() {
|
||||||
|
@Override
|
||||||
|
public void parse(
|
||||||
|
byte[] data,
|
||||||
|
int offset,
|
||||||
|
int length,
|
||||||
|
OutputOptions outputOptions,
|
||||||
|
Consumer<CuesWithTiming> output) {
|
||||||
|
lengthFromParse.set(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Format.CueReplacementBehavior int getCueReplacementBehavior() {
|
||||||
|
return Format.CUE_REPLACEMENT_BEHAVIOR_MERGE;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
SubtitleExtractor extractor =
|
||||||
|
new SubtitleExtractor(
|
||||||
|
fakeSubtitleParser, new Format.Builder().setSampleMimeType(MimeTypes.TEXT_VTT).build());
|
||||||
|
|
||||||
|
extractor.init(output);
|
||||||
|
while (extractor.read(input, null) != Extractor.RESULT_END_OF_INPUT) {}
|
||||||
|
|
||||||
|
assertThat(lengthFromParse.get()).isEqualTo(inputData.length);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void read_withoutInit_fails() {
|
public void read_withoutInit_fails() {
|
||||||
FakeExtractorInput input = new FakeExtractorInput.Builder().setData(new byte[0]).build();
|
FakeExtractorInput input = new FakeExtractorInput.Builder().setData(new byte[0]).build();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user