Skip to content

Commit

Permalink
Merge branch 'tresvecesseis-dev-v2-dvbsubs' into dev-v2
Browse files Browse the repository at this point in the history
  • Loading branch information
ojw28 committed Apr 6, 2017
2 parents 6caa3e7 + 538e71c commit 8c05b5b
Show file tree
Hide file tree
Showing 12 changed files with 1,861 additions and 10 deletions.
3 changes: 3 additions & 0 deletions library/core/proguard-rules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@
-keepclassmembers class com.google.android.exoplayer2.text.cea.Cea708Decoder {
public <init>(int);
}
-keepclassmembers class com.google.android.exoplayer2.text.dvb.DvbDecoder {
public <init>(java.util.List);
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ public Extractor[] createExtractors() {
private static final String CODEC_ID_SUBRIP = "S_TEXT/UTF8";
private static final String CODEC_ID_VOBSUB = "S_VOBSUB";
private static final String CODEC_ID_PGS = "S_HDMV/PGS";
private static final String CODEC_ID_DVBSUB = "S_DVBSUB";

private static final int VORBIS_MAX_INPUT_SIZE = 8192;
private static final int OPUS_MAX_INPUT_SIZE = 5760;
Expand Down Expand Up @@ -1233,7 +1234,8 @@ private static boolean isCodecSupported(String codecId) {
|| CODEC_ID_PCM_INT_LIT.equals(codecId)
|| CODEC_ID_SUBRIP.equals(codecId)
|| CODEC_ID_VOBSUB.equals(codecId)
|| CODEC_ID_PGS.equals(codecId);
|| CODEC_ID_PGS.equals(codecId)
|| CODEC_ID_DVBSUB.equals(codecId);
}

/**
Expand Down Expand Up @@ -1461,6 +1463,11 @@ public void initializeOutput(ExtractorOutput output, int trackId) throws ParserE
case CODEC_ID_PGS:
mimeType = MimeTypes.APPLICATION_PGS;
break;
case CODEC_ID_DVBSUB:
mimeType = MimeTypes.APPLICATION_DVBSUBS;
initializationData = Collections.singletonList(new byte[] {
(byte) 0x01, codecPrivate[0], codecPrivate[1], codecPrivate[2], codecPrivate[3]});
break;
default:
throw new ParserException("Unrecognized codec identifier.");
}
Expand Down Expand Up @@ -1495,7 +1502,8 @@ public void initializeOutput(ExtractorOutput output, int trackId) throws ParserE
format = Format.createTextSampleFormat(Integer.toString(trackId), mimeType, null,
Format.NO_VALUE, selectionFlags, language, drmInitData);
} else if (MimeTypes.APPLICATION_VOBSUB.equals(mimeType)
|| MimeTypes.APPLICATION_PGS.equals(mimeType)) {
|| MimeTypes.APPLICATION_PGS.equals(mimeType)
|| MimeTypes.APPLICATION_DVBSUBS.equals(mimeType)) {
type = C.TRACK_TYPE_TEXT;
format = Format.createImageSampleFormat(Integer.toString(trackId), mimeType, null,
Format.NO_VALUE, initializationData, language, drmInitData);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ public TsPayloadReader createPayloadReader(int streamType, EsInfo esInfo) {
? null : new SectionReader(new SpliceInfoSectionReader());
case TsExtractor.TS_STREAM_TYPE_ID3:
return new PesReader(new Id3Reader());
case TsExtractor.TS_STREAM_TYPE_DVBSUBS:
return new PesReader(new DvbSubtitlesReader(esInfo));
default:
return null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*
* Copyright (C) 2017 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 com.google.android.exoplayer2.extractor.ts;


import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.extractor.ExtractorOutput;
import com.google.android.exoplayer2.extractor.TrackOutput;
import com.google.android.exoplayer2.extractor.ts.TsPayloadReader.TrackIdGenerator;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.ParsableByteArray;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


/**
* Output PES packets to a {@link TrackOutput}.
*/
public final class DvbSubtitlesReader implements ElementaryStreamReader {

private class SubtitleTrack {
private String language;
private List<byte[]> initializationData;
}

private List<SubtitleTrack> subtitles = new ArrayList<>();

private long sampleTimeUs;
private int sampleBytesWritten;
private boolean writingSample;

private List<TrackOutput> outputTracks = new ArrayList<>();

public DvbSubtitlesReader(TsPayloadReader.EsInfo esInfo) {
int pos = 2;

while (pos < esInfo.descriptorBytes.length) {
SubtitleTrack subtitle = new SubtitleTrack();
subtitle.language = new String(new byte[] {
esInfo.descriptorBytes[pos],
esInfo.descriptorBytes[pos + 1],
esInfo.descriptorBytes[pos + 2]});

if (((esInfo.descriptorBytes[pos + 3] & 0xF0 ) >> 4 ) == 2 ) {
subtitle.language += " for hard of hearing";
}

subtitle.initializationData = Collections.singletonList(new byte[] {(byte) 0x00,
esInfo.descriptorBytes[pos + 4], esInfo.descriptorBytes[pos + 5],
esInfo.descriptorBytes[pos + 6], esInfo.descriptorBytes[pos + 7]});

subtitles.add(subtitle);
pos += 8;
}
}


@Override
public void seek() {
writingSample = false;
}

@Override
public void createTracks(ExtractorOutput extractorOutput, TrackIdGenerator idGenerator) {
TrackOutput output;
SubtitleTrack subtitle;

for (int i = 0; i < subtitles.size(); i++) {
subtitle = subtitles.get(i);
idGenerator.generateNewId();
output = extractorOutput.track(idGenerator.getTrackId(), C.TRACK_TYPE_TEXT);
output.format(Format.createImageSampleFormat(idGenerator.getFormatId(),
MimeTypes.APPLICATION_DVBSUBS, null, Format.NO_VALUE,
subtitle.initializationData, subtitle.language, null));
outputTracks.add(output);
}
}


@Override
public void packetStarted(long pesTimeUs, boolean dataAlignmentIndicator) {
if (!dataAlignmentIndicator) {
return;
}
writingSample = true;
sampleTimeUs = pesTimeUs;
sampleBytesWritten = 0;
}

@Override
public void packetFinished() {
TrackOutput output;

for (int i = 0; i < outputTracks.size(); i++) {
output = outputTracks.get(i);
output.sampleMetadata(sampleTimeUs, C.BUFFER_FLAG_KEY_FRAME, sampleBytesWritten, 0, null);
}
writingSample = false;
}

@Override
public void consume(ParsableByteArray data) {
if (writingSample) {
int bytesAvailable = data.bytesLeft();
TrackOutput output;
int dataPosition = data.getPosition();

for (int i = 0; i < outputTracks.size(); i++) {
data.setPosition(dataPosition);
output = outputTracks.get(i);
output.sampleData(data, bytesAvailable);
}

sampleBytesWritten += bytesAvailable;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ public Extractor[] createExtractors() {
public static final int TS_STREAM_TYPE_H265 = 0x24;
public static final int TS_STREAM_TYPE_ID3 = 0x15;
public static final int TS_STREAM_TYPE_SPLICE_INFO = 0x86;
public static final int TS_STREAM_TYPE_DVBSUBS = 0x59;

private static final int TS_PACKET_SIZE = 188;
private static final int TS_SYNC_BYTE = 0x47; // First byte of each TS packet.
Expand Down Expand Up @@ -356,6 +357,7 @@ private class PmtReader implements SectionPayloadReader {
private static final int TS_PMT_DESC_AC3 = 0x6A;
private static final int TS_PMT_DESC_EAC3 = 0x7A;
private static final int TS_PMT_DESC_DTS = 0x7B;
private static final int TS_PMT_DESC_DVBSUBS = 0x59;

private final ParsableBitArray pmtScratch;
private final int pid;
Expand Down Expand Up @@ -498,6 +500,9 @@ private EsInfo readEsInfo(ParsableByteArray data, int length) {
} else if (descriptorTag == TS_PMT_DESC_ISO639_LANG) {
language = new String(data.data, data.getPosition(), 3).trim();
// Audio type is ignored.
} else if (descriptorTag == TS_PMT_DESC_DVBSUBS) {
streamType = TS_STREAM_TYPE_DVBSUBS;
language = new String(data.data, data.getPosition(), 3).trim();
}
// Skip unused bytes of current descriptor.
data.skipBytes(positionOfNextDescriptor - data.getPosition());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,12 @@ public class Cue {
*/
public final float size;

/**
* The bitmap height as a fraction of the of the viewport size, or -1 if the bitmap should be
* displayed at its natural height given for its specified {@link #size}.
*/
public final float bitmapHeight;

/**
* Specifies whether or not the {@link #windowColor} property is set.
*/
Expand All @@ -190,11 +196,13 @@ public class Cue {
* @param verticalPositionAnchor The vertical anchor. One of {@link #ANCHOR_TYPE_START},
* {@link #ANCHOR_TYPE_MIDDLE}, {@link #ANCHOR_TYPE_END} and {@link #TYPE_UNSET}.
* @param width The width of the cue, expressed as a fraction of the viewport width.
* @param height The width of the cue, expressed as a fraction of the viewport width.
*/
public Cue(Bitmap bitmap, float horizontalPosition, @AnchorType int horizontalPositionAnchor,
float verticalPosition, @AnchorType int verticalPositionAnchor, float width) {
float verticalPosition, @AnchorType int verticalPositionAnchor, float width, float
height) {
this(null, null, bitmap, verticalPosition, LINE_TYPE_FRACTION, verticalPositionAnchor,
horizontalPosition, horizontalPositionAnchor, width, false, Color.BLACK);
horizontalPosition, horizontalPositionAnchor, width, height, false, Color.BLACK);
}

/**
Expand Down Expand Up @@ -240,15 +248,16 @@ public Cue(CharSequence text, Alignment textAlignment, float line, @LineType int
* @param windowColor See {@link #windowColor}.
*/
public Cue(CharSequence text, Alignment textAlignment, float line, @LineType int lineType,
@AnchorType int lineAnchor, float position, @AnchorType int positionAnchor, float size,
boolean windowColorSet, int windowColor) {
@AnchorType int lineAnchor, float position, @AnchorType int positionAnchor, float size,
boolean windowColorSet, int windowColor) {
this(text, textAlignment, null, line, lineType, lineAnchor, position, positionAnchor, size,
windowColorSet, windowColor);
-1, windowColorSet, windowColor);
}

private Cue(CharSequence text, Alignment textAlignment, Bitmap bitmap, float line,
@LineType int lineType, @AnchorType int lineAnchor, float position,
@AnchorType int positionAnchor, float size, boolean windowColorSet, int windowColor) {
@AnchorType int positionAnchor, float size, float bitmapHeight, boolean windowColorSet,
int windowColor) {
this.text = text;
this.textAlignment = textAlignment;
this.bitmap = bitmap;
Expand All @@ -258,6 +267,7 @@ private Cue(CharSequence text, Alignment textAlignment, Bitmap bitmap, float lin
this.position = position;
this.positionAnchor = positionAnchor;
this.size = size;
this.bitmapHeight = bitmapHeight;
this.windowColorSet = windowColorSet;
this.windowColor = windowColor;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import com.google.android.exoplayer2.text.webvtt.WebvttDecoder;
import com.google.android.exoplayer2.util.MimeTypes;

import java.util.List;

/**
* A factory for {@link SubtitleDecoder} instances.
*/
Expand Down Expand Up @@ -83,6 +85,8 @@ public SubtitleDecoder createDecoder(Format format) {
} else if (format.sampleMimeType.equals(MimeTypes.APPLICATION_CEA708)) {
return clazz.asSubclass(SubtitleDecoder.class).getConstructor(Integer.TYPE)
.newInstance(format.accessibilityChannel);
} else if (format.sampleMimeType.equals(MimeTypes.APPLICATION_DVBSUBS)) {
return clazz.asSubclass(SubtitleDecoder.class).getConstructor(List.class).newInstance(format.initializationData);
} else {
return clazz.asSubclass(SubtitleDecoder.class).getConstructor().newInstance();
}
Expand Down Expand Up @@ -112,6 +116,8 @@ private Class<?> getDecoderClass(String mimeType) {
return Class.forName("com.google.android.exoplayer2.text.cea.Cea608Decoder");
case MimeTypes.APPLICATION_CEA708:
return Class.forName("com.google.android.exoplayer2.text.cea.Cea708Decoder");
case MimeTypes.APPLICATION_DVBSUBS:
return Class.forName("com.google.android.exoplayer2.text.dvb.DvbDecoder");
default:
return null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright (C) 2017 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 com.google.android.exoplayer2.text.dvb;

import com.google.android.exoplayer2.text.SimpleSubtitleDecoder;

import java.util.List;

/**
* A {@link SimpleSubtitleDecoder} for DVB Subtitles.
*/
public final class DvbDecoder extends SimpleSubtitleDecoder {

private final DvbParser parser;

public DvbDecoder(List<byte[]> initializationData) {
super("DvbDecoder");

int subtitleCompositionPage = 1;
int subtitleAncillaryPage = 1;
int flags = 0;
byte[] tempByteArray;

if ((tempByteArray = initializationData.get(0)) != null && tempByteArray.length == 5) {
if (tempByteArray[0] == 0x01) {
flags |= DvbParser.FLAG_PES_STRIPPED_DVBSUB;
}
subtitleCompositionPage = ((tempByteArray[1] & 0xFF) << 8) | (tempByteArray[2] & 0xFF);
subtitleAncillaryPage = ((tempByteArray[3] & 0xFF) << 8) | (tempByteArray[4] & 0xFF);
}

parser = new DvbParser(subtitleCompositionPage, subtitleAncillaryPage, flags);
}

@Override
protected DvbSubtitle decode(byte[] data, int length) {
return new DvbSubtitle(parser.dvbSubsDecode(data, length));
}
}
Loading

0 comments on commit 8c05b5b

Please sign in to comment.