diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/text/SubtitleDecoderFactory.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/text/SubtitleDecoderFactory.java
index 667a1b0536..efec3fe893 100644
--- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/text/SubtitleDecoderFactory.java
+++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/text/SubtitleDecoderFactory.java
@@ -23,7 +23,7 @@ import androidx.media3.extractor.text.SubtitleDecoder;
import androidx.media3.extractor.text.cea.Cea608Decoder;
import androidx.media3.extractor.text.cea.Cea708Decoder;
import androidx.media3.extractor.text.dvb.DvbParser;
-import androidx.media3.extractor.text.pgs.PgsDecoder;
+import androidx.media3.extractor.text.pgs.PgsParser;
import androidx.media3.extractor.text.ssa.SsaParser;
import androidx.media3.extractor.text.subrip.SubripParser;
import androidx.media3.extractor.text.ttml.TtmlDecoder;
@@ -68,7 +68,7 @@ public interface SubtitleDecoderFactory {
*
Cea608 ({@link Cea608Decoder})
* Cea708 ({@link Cea708Decoder})
* DVB ({@link DvbParser})
- * PGS ({@link PgsDecoder})
+ * PGS ({@link PgsParser})
* Exoplayer Cues ({@link ExoplayerCuesDecoder})
*
*/
@@ -128,7 +128,8 @@ public interface SubtitleDecoderFactory {
"DelegatingSubtitleDecoderWithDvbParser",
new DvbParser(format.initializationData));
case MimeTypes.APPLICATION_PGS:
- return new PgsDecoder();
+ return new DelegatingSubtitleDecoder(
+ "DelegatingSubtitleDecoderWithPgsParser", new PgsParser());
case MimeTypes.TEXT_EXOPLAYER_CUES:
return new ExoplayerCuesDecoder();
default:
diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/text/pgs/PgsDecoder.java b/libraries/extractor/src/main/java/androidx/media3/extractor/text/pgs/PgsParser.java
similarity index 89%
rename from libraries/extractor/src/main/java/androidx/media3/extractor/text/pgs/PgsDecoder.java
rename to libraries/extractor/src/main/java/androidx/media3/extractor/text/pgs/PgsParser.java
index 000d2d13b4..95a76cdd9a 100644
--- a/libraries/extractor/src/main/java/androidx/media3/extractor/text/pgs/PgsDecoder.java
+++ b/libraries/extractor/src/main/java/androidx/media3/extractor/text/pgs/PgsParser.java
@@ -19,21 +19,21 @@ import static java.lang.Math.min;
import android.graphics.Bitmap;
import androidx.annotation.Nullable;
+import androidx.media3.common.C;
import androidx.media3.common.text.Cue;
import androidx.media3.common.util.ParsableByteArray;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
-import androidx.media3.extractor.text.SimpleSubtitleDecoder;
-import androidx.media3.extractor.text.Subtitle;
-import androidx.media3.extractor.text.SubtitleDecoderException;
+import androidx.media3.extractor.text.CuesWithTiming;
+import androidx.media3.extractor.text.SubtitleParser;
+import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.zip.Inflater;
-/** A {@link SimpleSubtitleDecoder} for PGS subtitles. */
+/** A {@link SubtitleParser} for PGS subtitles. */
@UnstableApi
-public final class PgsDecoder extends SimpleSubtitleDecoder {
+public final class PgsParser implements SubtitleParser {
private static final int SECTION_TYPE_PALETTE = 0x14;
private static final int SECTION_TYPE_BITMAP_PICTURE = 0x15;
@@ -45,20 +45,30 @@ public final class PgsDecoder extends SimpleSubtitleDecoder {
private final ParsableByteArray buffer;
private final ParsableByteArray inflatedBuffer;
private final CueBuilder cueBuilder;
-
+ private byte[] dataScratch = Util.EMPTY_BYTE_ARRAY;
@Nullable private Inflater inflater;
- public PgsDecoder() {
- super("PgsDecoder");
+ public PgsParser() {
buffer = new ParsableByteArray();
inflatedBuffer = new ParsableByteArray();
cueBuilder = new CueBuilder();
}
@Override
- protected Subtitle decode(byte[] data, int length, boolean reset)
- throws SubtitleDecoderException {
- buffer.reset(data, length);
+ public void reset() {}
+
+ @Override
+ public ImmutableList parse(byte[] data, int offset, int length) {
+ if (offset != 0) {
+ if (dataScratch.length < length) {
+ dataScratch = new byte[length];
+ }
+ System.arraycopy(
+ /* src= */ data, /* scrPos= */ offset, /* dest= */ dataScratch, /* destPos= */ 0, length);
+ buffer.reset(dataScratch, length);
+ } else {
+ buffer.reset(data, length);
+ }
maybeInflateData(buffer);
cueBuilder.reset();
ArrayList cues = new ArrayList<>();
@@ -68,7 +78,8 @@ public final class PgsDecoder extends SimpleSubtitleDecoder {
cues.add(cue);
}
}
- return new PgsSubtitle(Collections.unmodifiableList(cues));
+ return ImmutableList.of(
+ new CuesWithTiming(cues, /* startTimeUs= */ C.TIME_UNSET, /* durationUs= */ C.TIME_UNSET));
}
private void maybeInflateData(ParsableByteArray buffer) {
diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/text/pgs/PgsSubtitle.java b/libraries/extractor/src/main/java/androidx/media3/extractor/text/pgs/PgsSubtitle.java
deleted file mode 100644
index b82a704132..0000000000
--- a/libraries/extractor/src/main/java/androidx/media3/extractor/text/pgs/PgsSubtitle.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package androidx.media3.extractor.text.pgs;
-
-import androidx.media3.common.C;
-import androidx.media3.common.text.Cue;
-import androidx.media3.extractor.text.Subtitle;
-import java.util.List;
-
-/** A representation of a PGS subtitle. */
-/* package */ final class PgsSubtitle implements Subtitle {
-
- private final List cues;
-
- public PgsSubtitle(List cues) {
- this.cues = cues;
- }
-
- @Override
- public int getNextEventTimeIndex(long timeUs) {
- return C.INDEX_UNSET;
- }
-
- @Override
- public int getEventTimeCount() {
- return 1;
- }
-
- @Override
- public long getEventTime(int index) {
- return 0;
- }
-
- @Override
- public List getCues(long timeUs) {
- return cues;
- }
-}