mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
support zlib compressed PGS subtitles
This commit is contained in:
parent
aa57062199
commit
5d1c84cebc
@ -25,6 +25,10 @@ import com.google.android.exoplayer2.util.Util;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.zip.InflaterInputStream;
|
||||
|
||||
/** A {@link SimpleSubtitleDecoder} for PGS subtitles. */
|
||||
public final class PgsDecoder extends SimpleSubtitleDecoder {
|
||||
@ -34,18 +38,29 @@ public final class PgsDecoder extends SimpleSubtitleDecoder {
|
||||
private static final int SECTION_TYPE_IDENTIFIER = 0x16;
|
||||
private static final int SECTION_TYPE_END = 0x80;
|
||||
|
||||
private static final int INFLATE_HEADER = 0x78;
|
||||
private static final int INFLATE_BUFFER_SIZE = 5;
|
||||
|
||||
private final ParsableByteArray buffer;
|
||||
private final CueBuilder cueBuilder;
|
||||
private final ByteArrayOutputStream inflateBuffer;
|
||||
private final byte[] inflateReadBuffer;
|
||||
|
||||
public PgsDecoder() {
|
||||
super("PgsDecoder");
|
||||
buffer = new ParsableByteArray();
|
||||
cueBuilder = new CueBuilder();
|
||||
inflateBuffer = new ByteArrayOutputStream();
|
||||
inflateReadBuffer = new byte[INFLATE_BUFFER_SIZE];
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Subtitle decode(byte[] data, int size, boolean reset) throws SubtitleDecoderException {
|
||||
buffer.reset(data, size);
|
||||
byte[] inflated = tryInflateBuffer(data, size);
|
||||
if (inflated == null)
|
||||
buffer.reset(data, size);
|
||||
else
|
||||
buffer.reset(inflated, inflated.length);
|
||||
cueBuilder.reset();
|
||||
ArrayList<Cue> cues = new ArrayList<>();
|
||||
while (buffer.bytesLeft() >= 3) {
|
||||
@ -57,6 +72,25 @@ public final class PgsDecoder extends SimpleSubtitleDecoder {
|
||||
return new PgsSubtitle(Collections.unmodifiableList(cues));
|
||||
}
|
||||
|
||||
private byte[] tryInflateBuffer(byte[] data, int size) {
|
||||
if (size > 0 && (((int) data[0]) & 0xff) != INFLATE_HEADER) return null;
|
||||
|
||||
inflateBuffer.reset();
|
||||
|
||||
try {
|
||||
InflaterInputStream iis = new InflaterInputStream(new ByteArrayInputStream(data, 0, size));
|
||||
int len = -1;
|
||||
|
||||
while ((len = iis.read(inflateReadBuffer)) != -1) {
|
||||
inflateBuffer.write(inflateReadBuffer, 0, len);
|
||||
}
|
||||
return inflateBuffer.toByteArray();
|
||||
}
|
||||
catch (IOException e) { }
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Cue readNextSection(ParsableByteArray buffer, CueBuilder cueBuilder) {
|
||||
int limit = buffer.limit();
|
||||
int sectionType = buffer.readUnsignedByte();
|
||||
|
Loading…
x
Reference in New Issue
Block a user