PgsParser implementation - moved from PgsDecoder

`PgsDecoder` which used to be `SimpleSubtitleDecoder` will now be called `PgsParser` and implement `SubtitleParser` interface. For backwards compatibility, we will have the same functionality provided by `DelegatingSubtitleDecoder` backed-up by a new `PgsParser` instance.

PiperOrigin-RevId: 548520549
This commit is contained in:
jbibik 2023-07-16 20:30:16 +01:00 committed by Ian Baker
parent 0c29dacde3
commit 7d4848ece2
3 changed files with 28 additions and 67 deletions

View File

@ -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 {
* <li>Cea608 ({@link Cea608Decoder})
* <li>Cea708 ({@link Cea708Decoder})
* <li>DVB ({@link DvbParser})
* <li>PGS ({@link PgsDecoder})
* <li>PGS ({@link PgsParser})
* <li>Exoplayer Cues ({@link ExoplayerCuesDecoder})
* </ul>
*/
@ -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:

View File

@ -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 {
public void reset() {}
@Override
public ImmutableList<CuesWithTiming> 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<Cue> 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) {

View File

@ -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<Cue> cues;
public PgsSubtitle(List<Cue> 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<Cue> getCues(long timeUs) {
return cues;
}
}