Pull request review fixes

parent 6c9656dc
...@@ -5,3 +5,6 @@ ...@@ -5,3 +5,6 @@
-keepclassmembers class com.google.android.exoplayer2.text.cea.Cea708Decoder { -keepclassmembers class com.google.android.exoplayer2.text.cea.Cea708Decoder {
public <init>(int); public <init>(int);
} }
-keepclassmembers class com.google.android.exoplayer2.text.dvb.DvbDecoder {
public <init>(java.util.List);
}
\ No newline at end of file
...@@ -1235,7 +1235,8 @@ public final class MatroskaExtractor implements Extractor { ...@@ -1235,7 +1235,8 @@ public final class MatroskaExtractor implements Extractor {
|| CODEC_ID_SUBRIP.equals(codecId) || CODEC_ID_SUBRIP.equals(codecId)
|| CODEC_ID_VOBSUB.equals(codecId) || CODEC_ID_VOBSUB.equals(codecId)
|| CODEC_ID_PGS.equals(codecId) || CODEC_ID_PGS.equals(codecId)
|| CODEC_ID_DVBSUB.equals(codecId); } || CODEC_ID_DVBSUB.equals(codecId);
}
/** /**
* Returns an array that can store (at least) {@code length} elements, which will be either a new * Returns an array that can store (at least) {@code length} elements, which will be either a new
...@@ -1464,11 +1465,8 @@ public final class MatroskaExtractor implements Extractor { ...@@ -1464,11 +1465,8 @@ public final class MatroskaExtractor implements Extractor {
break; break;
case CODEC_ID_DVBSUB: case CODEC_ID_DVBSUB:
mimeType = MimeTypes.APPLICATION_DVBSUBS; mimeType = MimeTypes.APPLICATION_DVBSUBS;
initializationData = new ArrayList<>(4); initializationData = Collections.singletonList(new byte[] {
initializationData.add(null); (byte) 0x01, codecPrivate[0], codecPrivate[1], codecPrivate[2], codecPrivate[3]});
initializationData.add(new byte[] {codecPrivate[0], codecPrivate[1]});
initializationData.add(new byte[] {codecPrivate[2], codecPrivate[3]});
initializationData.add("mkv".getBytes());
break; break;
default: default:
throw new ParserException("Unrecognized codec identifier."); throw new ParserException("Unrecognized codec identifier.");
......
...@@ -24,29 +24,29 @@ import com.google.android.exoplayer2.extractor.ts.TsPayloadReader.TrackIdGenerat ...@@ -24,29 +24,29 @@ import com.google.android.exoplayer2.extractor.ts.TsPayloadReader.TrackIdGenerat
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.ParsableByteArray;
import java.util.ArrayList; import java.util.Collections;
import java.util.List; import java.util.List;
public class DvbSubtitlesReader implements ElementaryStreamReader { /**
* Output PES packets to a {@link TrackOutput}.
*/
public final class DvbSubtitlesReader implements ElementaryStreamReader {
private static final String TAG= "DVBSubsReader";
private final String language; private final String language;
private List<byte[]> initializationData = new ArrayList<>(); private List<byte[]> initializationData;
private long sampleTimeUs; private long sampleTimeUs;
private int totalBytesWritten; private int sampleBytesWritten;
private boolean writingSample; private boolean writingSample;
private TrackOutput output; private TrackOutput output;
public DvbSubtitlesReader(TsPayloadReader.EsInfo esInfo) { public DvbSubtitlesReader(TsPayloadReader.EsInfo esInfo) {
// we only support one subtitle service per PID
this.language = esInfo.language; this.language = esInfo.language;
this.initializationData.add(new byte[] {esInfo.descriptorBytes[5]}); // subtitle subtype initializationData = Collections.singletonList(new byte[] {(byte) 0x00,
this.initializationData.add(new byte[] {esInfo.descriptorBytes[6], esInfo.descriptorBytes[7]}); // subtitle compose page esInfo.descriptorBytes[6], esInfo.descriptorBytes[7],
this.initializationData.add(new byte[] {esInfo.descriptorBytes[8], esInfo.descriptorBytes[9]}); // subtitle ancillary page esInfo.descriptorBytes[8], esInfo.descriptorBytes[9]});
this.initializationData.add("mp2t".getBytes());
} }
...@@ -59,7 +59,8 @@ public class DvbSubtitlesReader implements ElementaryStreamReader { ...@@ -59,7 +59,8 @@ public class DvbSubtitlesReader implements ElementaryStreamReader {
public void createTracks(ExtractorOutput extractorOutput, TrackIdGenerator idGenerator) { public void createTracks(ExtractorOutput extractorOutput, TrackIdGenerator idGenerator) {
idGenerator.generateNewId(); idGenerator.generateNewId();
this.output = extractorOutput.track(idGenerator.getTrackId(), C.TRACK_TYPE_TEXT); this.output = extractorOutput.track(idGenerator.getTrackId(), C.TRACK_TYPE_TEXT);
output.format(Format.createImageSampleFormat(idGenerator.getFormatId(), MimeTypes.APPLICATION_DVBSUBS, null, Format.NO_VALUE, initializationData, language, null)); output.format(Format.createImageSampleFormat(idGenerator.getFormatId(),
MimeTypes.APPLICATION_DVBSUBS, null, Format.NO_VALUE, initializationData, language, null));
} }
...@@ -70,20 +71,21 @@ public class DvbSubtitlesReader implements ElementaryStreamReader { ...@@ -70,20 +71,21 @@ public class DvbSubtitlesReader implements ElementaryStreamReader {
} }
writingSample = true; writingSample = true;
sampleTimeUs = pesTimeUs; sampleTimeUs = pesTimeUs;
totalBytesWritten = 0; sampleBytesWritten = 0;
} }
@Override @Override
public void packetFinished() { public void packetFinished() {
output.sampleMetadata(sampleTimeUs, C.BUFFER_FLAG_KEY_FRAME, totalBytesWritten, 0, null); output.sampleMetadata(sampleTimeUs, C.BUFFER_FLAG_KEY_FRAME, sampleBytesWritten, 0, null);
writingSample = false; writingSample = false;
} }
@Override @Override
public void consume(ParsableByteArray data) { public void consume(ParsableByteArray data) {
if (writingSample) { if (writingSample) {
totalBytesWritten += data.bytesLeft(); int bytesAvailable = data.bytesLeft();
output.sampleData(data, data.bytesLeft()); output.sampleData(data, bytesAvailable);
sampleBytesWritten += bytesAvailable;
} }
} }
} }
\ No newline at end of file
...@@ -502,7 +502,6 @@ public final class TsExtractor implements Extractor { ...@@ -502,7 +502,6 @@ public final class TsExtractor implements Extractor {
// Audio type is ignored. // Audio type is ignored.
} else if (descriptorTag == TS_PMT_DESC_DVBSUBS) { } else if (descriptorTag == TS_PMT_DESC_DVBSUBS) {
streamType = TS_STREAM_TYPE_DVBSUBS; streamType = TS_STREAM_TYPE_DVBSUBS;
// we only support one subtitle service per PID
language = new String(data.data, data.getPosition(), 3).trim(); language = new String(data.data, data.getPosition(), 3).trim();
} }
// Skip unused bytes of current descriptor. // Skip unused bytes of current descriptor.
......
...@@ -168,6 +168,12 @@ public class Cue { ...@@ -168,6 +168,12 @@ public class Cue {
public final float size; 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. * Specifies whether or not the {@link #windowColor} property is set.
*/ */
public final boolean windowColorSet; public final boolean windowColorSet;
...@@ -178,30 +184,6 @@ public class Cue { ...@@ -178,30 +184,6 @@ public class Cue {
public final int windowColor; public final int windowColor;
/** /**
* The Storage Aspect Ratio of the Cue
*/
public final float sar;
/** * Creates an image cue.
*
* @param bitmap See {@link #bitmap}.
* @param horizontalPosition The position of the horizontal anchor within the viewport, expressed
* as a fraction of the viewport width.
* @param horizontalPositionAnchor The horizontal anchor. One of {@link #ANCHOR_TYPE_START},
* {@link #ANCHOR_TYPE_MIDDLE}, {@link #ANCHOR_TYPE_END} and {@link #TYPE_UNSET}.
* @param verticalPosition The position of the vertical anchor within the viewport, expressed as a
* fraction of the viewport height.
* @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.
*/
public Cue(Bitmap bitmap, float horizontalPosition, @AnchorType int horizontalPositionAnchor,
float verticalPosition, @AnchorType int verticalPositionAnchor, float width) {
this(null, null, bitmap, verticalPosition, LINE_TYPE_FRACTION, verticalPositionAnchor,
horizontalPosition, horizontalPositionAnchor, width, false, Color.BLACK, (float) 1.7777);
}
/**
* Creates an image cue. * Creates an image cue.
* *
* @param bitmap See {@link #bitmap}. * @param bitmap See {@link #bitmap}.
...@@ -214,12 +196,13 @@ public class Cue { ...@@ -214,12 +196,13 @@ public class Cue {
* @param verticalPositionAnchor The vertical anchor. One of {@link #ANCHOR_TYPE_START}, * @param verticalPositionAnchor The vertical anchor. One of {@link #ANCHOR_TYPE_START},
* {@link #ANCHOR_TYPE_MIDDLE}, {@link #ANCHOR_TYPE_END} and {@link #TYPE_UNSET}. * {@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 width The width of the cue, expressed as a fraction of the viewport width.
* @param sar The Storage Aspect Ratio of the cue, defaults to FHD SAR unless otherwise specified. * @param height The width of the cue, expressed as a fraction of the viewport width.
*/ */
public Cue(Bitmap bitmap, float horizontalPosition, @AnchorType int horizontalPositionAnchor, public Cue(Bitmap bitmap, float horizontalPosition, @AnchorType int horizontalPositionAnchor,
float verticalPosition, @AnchorType int verticalPositionAnchor, float width, float sar) { float verticalPosition, @AnchorType int verticalPositionAnchor, float width, float
height) {
this(null, null, bitmap, verticalPosition, LINE_TYPE_FRACTION, verticalPositionAnchor, this(null, null, bitmap, verticalPosition, LINE_TYPE_FRACTION, verticalPositionAnchor,
horizontalPosition, horizontalPositionAnchor, width, false, Color.BLACK, sar); horizontalPosition, horizontalPositionAnchor, width, height, false, Color.BLACK);
} }
/** /**
...@@ -268,12 +251,13 @@ public class Cue { ...@@ -268,12 +251,13 @@ public class Cue {
@AnchorType int lineAnchor, float position, @AnchorType int positionAnchor, float size, @AnchorType int lineAnchor, float position, @AnchorType int positionAnchor, float size,
boolean windowColorSet, int windowColor) { boolean windowColorSet, int windowColor) {
this(text, textAlignment, null, line, lineType, lineAnchor, position, positionAnchor, size, this(text, textAlignment, null, line, lineType, lineAnchor, position, positionAnchor, size,
windowColorSet, windowColor, 1); -1, windowColorSet, windowColor);
} }
private Cue(CharSequence text, Alignment textAlignment, Bitmap bitmap, float line, private Cue(CharSequence text, Alignment textAlignment, Bitmap bitmap, float line,
@LineType int lineType, @AnchorType int lineAnchor, float position, @LineType int lineType, @AnchorType int lineAnchor, float position,
@AnchorType int positionAnchor, float size, boolean windowColorSet, int windowColor, float sar) { @AnchorType int positionAnchor, float size, float bitmapHeight, boolean windowColorSet,
int windowColor) {
this.text = text; this.text = text;
this.textAlignment = textAlignment; this.textAlignment = textAlignment;
this.bitmap = bitmap; this.bitmap = bitmap;
...@@ -283,9 +267,9 @@ public class Cue { ...@@ -283,9 +267,9 @@ public class Cue {
this.position = position; this.position = position;
this.positionAnchor = positionAnchor; this.positionAnchor = positionAnchor;
this.size = size; this.size = size;
this.bitmapHeight = bitmapHeight;
this.windowColorSet = windowColorSet; this.windowColorSet = windowColorSet;
this.windowColor = windowColor; this.windowColor = windowColor;
this.sar = sar;
} }
} }
...@@ -85,7 +85,7 @@ public interface SubtitleDecoderFactory { ...@@ -85,7 +85,7 @@ public interface SubtitleDecoderFactory {
} else if (format.sampleMimeType.equals(MimeTypes.APPLICATION_CEA708)) { } else if (format.sampleMimeType.equals(MimeTypes.APPLICATION_CEA708)) {
return clazz.asSubclass(SubtitleDecoder.class).getConstructor(Integer.TYPE) return clazz.asSubclass(SubtitleDecoder.class).getConstructor(Integer.TYPE)
.newInstance(format.accessibilityChannel); .newInstance(format.accessibilityChannel);
} else if (format.sampleMimeType.equals(MimeTypes.APPLICATION_DVBSUBS) && format.initializationData != null) { } else if (format.sampleMimeType.equals(MimeTypes.APPLICATION_DVBSUBS)) {
return clazz.asSubclass(SubtitleDecoder.class).getConstructor(List.class).newInstance(format.initializationData); return clazz.asSubclass(SubtitleDecoder.class).getConstructor(List.class).newInstance(format.initializationData);
} else { } else {
return clazz.asSubclass(SubtitleDecoder.class).getConstructor().newInstance(); return clazz.asSubclass(SubtitleDecoder.class).getConstructor().newInstance();
...@@ -117,7 +117,7 @@ public interface SubtitleDecoderFactory { ...@@ -117,7 +117,7 @@ public interface SubtitleDecoderFactory {
case MimeTypes.APPLICATION_CEA708: case MimeTypes.APPLICATION_CEA708:
return Class.forName("com.google.android.exoplayer2.text.cea.Cea708Decoder"); return Class.forName("com.google.android.exoplayer2.text.cea.Cea708Decoder");
case MimeTypes.APPLICATION_DVBSUBS: case MimeTypes.APPLICATION_DVBSUBS:
return Class.forName("com.google.android.exoplayer2.text.dvbsubs.DvbSubsDecoder"); return Class.forName("com.google.android.exoplayer2.text.dvb.DvbDecoder");
default: default:
return null; return null;
} }
......
/*
* 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));
}
}
\ No newline at end of file
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.android.exoplayer2.text.dvbsubs; package com.google.android.exoplayer2.text.dvb;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Canvas; import android.graphics.Canvas;
...@@ -37,16 +37,18 @@ import java.util.List; ...@@ -37,16 +37,18 @@ import java.util.List;
/** /**
* Parse and generate a list of {@link Cue}s from DVB subtitling bitstream * Parse and generate a list of {@link Cue}s from DVB subtitling bitstream
*/ */
public class DvbSubtitlesParser { public class DvbParser {
private static final String TAG = "DVBSubs"; private static final String TAG = "DVBSubs";
@IntDef(flag = true, value = {FLAG_PES_STRIPPED_DVBSUB}) @IntDef(flag = true, value = {FLAG_PES_STRIPPED_DVBSUB})
public @interface Flags { public @interface Flags {
} }
public static final int FLAG_PES_STRIPPED_DVBSUB = 1; public static final int FLAG_PES_STRIPPED_DVBSUB = 1;
@Flags private final int flags; @Flags
private final int flags;
/* List of different SEGMENT TYPES */ /* List of different SEGMENT TYPES */
/* According to EN 300-743, table 2 */ /* According to EN 300-743, table 2 */
...@@ -99,8 +101,8 @@ public class DvbSubtitlesParser { ...@@ -99,8 +101,8 @@ public class DvbSubtitlesParser {
/* Clut mapping tables */ /* Clut mapping tables */
/* According to EN 300-743, 10.4 10.5 10.6 */ /* According to EN 300-743, 10.4 10.5 10.6 */
private byte[] defaultMap24 = {(byte) 0x00, (byte) 0x07, (byte) 0x08, (byte) 0x0f }; private byte[] defaultMap24 = {(byte) 0x00, (byte) 0x07, (byte) 0x08, (byte) 0x0f};
private byte[] defaultMap28 = {(byte) 0x00, (byte) 0x77, (byte) 0x88, (byte) 0xff }; private byte[] defaultMap28 = {(byte) 0x00, (byte) 0x77, (byte) 0x88, (byte) 0xff};
private byte[] defaultMap48 = {(byte) 0x00, (byte) 0x11, (byte) 0x22, (byte) 0x33, private byte[] defaultMap48 = {(byte) 0x00, (byte) 0x11, (byte) 0x22, (byte) 0x33,
(byte) 0x44, (byte) 0x55, (byte) 0x66, (byte) 0x77, (byte) 0x44, (byte) 0x55, (byte) 0x66, (byte) 0x77,
(byte) 0x88, (byte) 0x99, (byte) 0xaa, (byte) 0xbb, (byte) 0x88, (byte) 0x99, (byte) 0xaa, (byte) 0xbb,
...@@ -113,9 +115,6 @@ public class DvbSubtitlesParser { ...@@ -113,9 +115,6 @@ public class DvbSubtitlesParser {
private final static int OBJECT_NON_MODIFYING_COLOUR_FLAG = 0x01; private final static int OBJECT_NON_MODIFYING_COLOUR_FLAG = 0x01;
/* Constants */
private static final int UNDEF_PAGE = -1;
/* instance variables */ /* instance variables */
private Paint defaultPaint = new Paint(); private Paint defaultPaint = new Paint();
private Paint fillRegionPaint = new Paint(); private Paint fillRegionPaint = new Paint();
...@@ -233,7 +232,7 @@ public class DvbSubtitlesParser { ...@@ -233,7 +232,7 @@ public class DvbSubtitlesParser {
byte B; byte B;
int ARGB; int ARGB;
void clutYCbCrT (int Y, int Cb, int Cr, int T) { void clutYCbCrT(int Y, int Cb, int Cr, int T) {
this.Y = (byte) Y; this.Y = (byte) Y;
this.Cb = (byte) Cb; this.Cb = (byte) Cb;
...@@ -265,7 +264,7 @@ public class DvbSubtitlesParser { ...@@ -265,7 +264,7 @@ public class DvbSubtitlesParser {
} }
void clutRGBA (int R, int G, int B, int A) { void clutRGBA(int R, int G, int B, int A) {
this.A = (byte) A; this.A = (byte) A;
this.R = (byte) R; this.R = (byte) R;
...@@ -278,9 +277,9 @@ public class DvbSubtitlesParser { ...@@ -278,9 +277,9 @@ public class DvbSubtitlesParser {
((G & 0xFF) << 8) | ((G & 0xFF) << 8) |
(B & 0xFF); (B & 0xFF);
int y = (int) ( 0.299000 * R + 0.587000 * G + 0.114000 * B); int y = (int) (0.299000 * R + 0.587000 * G + 0.114000 * B);
int Cb = 128 + (int) (-0.168736 * R + -0.331264 * G + 0.500000 * B); int Cb = 128 + (int) (-0.168736 * R + -0.331264 * G + 0.500000 * B);
int Cr = 128 + (int) ( 0.500000 * R + -0.418688 * G + -0.081312 * B); int Cr = 128 + (int) (0.500000 * R + -0.418688 * G + -0.081312 * B);
if (y > 255) this.Y = (byte) 255; if (y > 255) this.Y = (byte) 255;
else if (y < 0) this.Y = 0; else if (y < 0) this.Y = 0;
...@@ -406,7 +405,7 @@ public class DvbSubtitlesParser { ...@@ -406,7 +405,7 @@ public class DvbSubtitlesParser {
return entries; return entries;
} }
ClutDefinition () { ClutDefinition() {
clutEntries2bit = generateDefault2bitClut(); clutEntries2bit = generateDefault2bitClut();
clutEntries4bit = generateDefault4bitClut(); clutEntries4bit = generateDefault4bitClut();
clutEntries8bit = generateDefault8bitClut(); clutEntries8bit = generateDefault8bitClut();
...@@ -429,33 +428,6 @@ public class DvbSubtitlesParser { ...@@ -429,33 +428,6 @@ public class DvbSubtitlesParser {
} }
/** /**
* Construct a subtitle service with default subtitle pageId
*/
DvbSubtitlesParser() {
this(1);
}
/**
* Construct a subtitle service for the given subtitle pageId
*
* @param subtitlePageId The subtitle page Id carrying the selected subtitle track
*/
DvbSubtitlesParser(int subtitlePageId) {
this(subtitlePageId, UNDEF_PAGE);
}
/**
* Construct a subtitle service for the given subtitle and ancillary pageIds
*
* @param subtitlePageId The Id of the subtitle page carrying the selected subtitle track
* @param ancillaryPageId Id of the common subtitle page containing additional data for the current
* subtitle track
*/
DvbSubtitlesParser(int subtitlePageId, int ancillaryPageId) {
this(subtitlePageId, ancillaryPageId, 0);
}
/**
* Construct a subtitle service for the given subtitle and ancillary pageIds * Construct a subtitle service for the given subtitle and ancillary pageIds
* *
* @param subtitlePageId The Id of the subtitle page carrying the selected subtitle track * @param subtitlePageId The Id of the subtitle page carrying the selected subtitle track
...@@ -463,7 +435,7 @@ public class DvbSubtitlesParser { ...@@ -463,7 +435,7 @@ public class DvbSubtitlesParser {
* subtitle track * subtitle track
* @param flags additional initialisation info to properly configure the parser * @param flags additional initialisation info to properly configure the parser
*/ */
DvbSubtitlesParser(int subtitlePageId, int ancillaryPageId, @Flags int flags) { DvbParser(int subtitlePageId, int ancillaryPageId, @Flags int flags) {
this.subtitleService = new SubtitleService(); this.subtitleService = new SubtitleService();
this.flags = flags; this.flags = flags;
...@@ -477,7 +449,7 @@ public class DvbSubtitlesParser { ...@@ -477,7 +449,7 @@ public class DvbSubtitlesParser {
this.debugRegionPaint.setColor(0xff00ff00); this.debugRegionPaint.setColor(0xff00ff00);
this.debugRegionPaint.setStyle(Paint.Style.STROKE); this.debugRegionPaint.setStyle(Paint.Style.STROKE);
this.debugRegionPaint.setPathEffect(new DashPathEffect(new float[] {2,2}, 0)); this.debugRegionPaint.setPathEffect(new DashPathEffect(new float[]{2, 2}, 0));
this.debugObjectPaint.setColor(0xffff0000); this.debugObjectPaint.setColor(0xffff0000);
this.debugObjectPaint.setStyle(Paint.Style.STROKE); this.debugObjectPaint.setStyle(Paint.Style.STROKE);
...@@ -525,7 +497,8 @@ public class DvbSubtitlesParser { ...@@ -525,7 +497,8 @@ public class DvbSubtitlesParser {
subtitleService.displayDefinition.versionNumber = tempDisplay.versionNumber; subtitleService.displayDefinition.versionNumber = tempDisplay.versionNumber;
} }
if (BuildConfig.DEBUG) Log.d(TAG + "/DDS", " [versionNumber] = " + tempDisplay.versionNumber + if (BuildConfig.DEBUG)
Log.d(TAG + "/DDS", " [versionNumber] = " + tempDisplay.versionNumber +
" [width/height] = " + (tempDisplay.displayWidth + 1) + "/" + (tempDisplay.displayHeight + 1) + " [width/height] = " + (tempDisplay.displayWidth + 1) + "/" + (tempDisplay.displayHeight + 1) +
" Window[minX/minY/maxX/maxY] = " + tempDisplay.displayWindowHorizontalPositionMinimum + " Window[minX/minY/maxX/maxY] = " + tempDisplay.displayWindowHorizontalPositionMinimum +
"/" + tempDisplay.displayWindowVerticalPositionMinimum + "/" + tempDisplay.displayWindowVerticalPositionMinimum +
...@@ -553,7 +526,7 @@ public class DvbSubtitlesParser { ...@@ -553,7 +526,7 @@ public class DvbSubtitlesParser {
case DVBSUB_ST_CLUT_DEFINITION: case DVBSUB_ST_CLUT_DEFINITION:
if (BuildConfig.DEBUG) Log.d(TAG, " Parse Clut Definition segment."); if (BuildConfig.DEBUG) Log.d(TAG, " Parse Clut Definition segment.");
ClutDefinition tempClutDefinition = parseClutDefinitionSegment(); ClutDefinition tempClutDefinition = parseClutDefinitionSegment();
if (tempClutDefinition != null ) { if (tempClutDefinition != null) {
if (tempClutDefinition.pageId == subtitleService.subtitlePageId) { if (tempClutDefinition.pageId == subtitleService.subtitlePageId) {
subtitleService.cluts.put(tempClutDefinition.clutId, tempClutDefinition); subtitleService.cluts.put(tempClutDefinition.clutId, tempClutDefinition);
} else if (tempClutDefinition.pageId == subtitleService.ancillaryPageId) { } else if (tempClutDefinition.pageId == subtitleService.ancillaryPageId) {
...@@ -575,7 +548,8 @@ public class DvbSubtitlesParser { ...@@ -575,7 +548,8 @@ public class DvbSubtitlesParser {
case DVBSUB_ST_ENDOFDISPLAY: case DVBSUB_ST_ENDOFDISPLAY:
pageId = tsStream.readBits(16); pageId = tsStream.readBits(16);
segmentLength = tsStream.readBits(16); segmentLength = tsStream.readBits(16);
if (BuildConfig.DEBUG) Log.d(TAG, "pageId " + pageId + "end of display size = " + segmentLength); if (BuildConfig.DEBUG)
Log.d(TAG, "pageId " + pageId + "end of display size = " + segmentLength);
tsStream.skipBits(segmentLength * 8); tsStream.skipBits(segmentLength * 8);
break; break;
case DVBSUB_ST_STUFFING: case DVBSUB_ST_STUFFING:
...@@ -998,7 +972,7 @@ public class DvbSubtitlesParser { ...@@ -998,7 +972,7 @@ public class DvbSubtitlesParser {
return object; return object;
} }
private Bitmap parsePixelDataSubBlocks (ObjectData object, ClutDefinition clut, int regionDepth, private Bitmap parsePixelDataSubBlocks(ObjectData object, ClutDefinition clut, int regionDepth,
int horizontalAddress, int verticalAddress) { int horizontalAddress, int verticalAddress) {
/* Parse pixel-data sub-block. ETSI EN 300 743 7.2.5.1 /* Parse pixel-data sub-block. ETSI EN 300 743 7.2.5.1
...@@ -1052,8 +1026,8 @@ public class DvbSubtitlesParser { ...@@ -1052,8 +1026,8 @@ public class DvbSubtitlesParser {
int lineHeight; int lineHeight;
ParsableBitArray[] pixelData = new ParsableBitArray[2]; ParsableBitArray[] pixelData = new ParsableBitArray[2];
pixelData[0]= new ParsableBitArray(object.topFieldData); pixelData[0] = new ParsableBitArray(object.topFieldData);
if ( object.bottomFieldDataLength == 0) { if (object.bottomFieldDataLength == 0) {
lineHeight = 2; lineHeight = 2;
} else { } else {
lineHeight = 1; lineHeight = 1;
...@@ -1430,7 +1404,7 @@ public class DvbSubtitlesParser { ...@@ -1430,7 +1404,7 @@ public class DvbSubtitlesParser {
} }
} }
if (BuildConfig.DEBUG) Log.d(TAG,"New PES subtitle packet."); if (BuildConfig.DEBUG) Log.d(TAG, "New PES subtitle packet.");
int sync = tsStream.readBits(8); int sync = tsStream.readBits(8);
// test for segment Sync Byte and account for possible additional wordalign byte in Object data segment // test for segment Sync Byte and account for possible additional wordalign byte in Object data segment
...@@ -1459,11 +1433,11 @@ public class DvbSubtitlesParser { ...@@ -1459,11 +1433,11 @@ public class DvbSubtitlesParser {
(subtitleService.displayDefinition.displayWindowHorizontalPositionMaximum - (subtitleService.displayDefinition.displayWindowHorizontalPositionMaximum -
subtitleService.displayDefinition.displayWindowHorizontalPositionMinimum) + "/" + subtitleService.displayDefinition.displayWindowHorizontalPositionMinimum) + "/" +
(subtitleService.displayDefinition.displayWindowVerticalPositionMaximum - (subtitleService.displayDefinition.displayWindowVerticalPositionMaximum -
subtitleService.displayDefinition.displayWindowVerticalPositionMinimum) + ")" ); subtitleService.displayDefinition.displayWindowVerticalPositionMinimum) + ")");
} }
} }
int a,b; int a, b;
PageRegion pageRegion; PageRegion pageRegion;
RegionComposition regionComposition; RegionComposition regionComposition;
int baseHorizontalAddress, baseVerticalAddress; int baseHorizontalAddress, baseVerticalAddress;
...@@ -1518,7 +1492,7 @@ public class DvbSubtitlesParser { ...@@ -1518,7 +1492,7 @@ public class DvbSubtitlesParser {
RegionObject regionObject; RegionObject regionObject;
int objectKey; int objectKey;
// process regions compositions // process regions compositions
for ( b = 0; b < regionComposition.regionObjects.size(); b++) { for (b = 0; b < regionComposition.regionObjects.size(); b++) {
objectKey = regionComposition.regionObjects.keyAt(b); objectKey = regionComposition.regionObjects.keyAt(b);
regionObject = regionComposition.regionObjects.get(objectKey); regionObject = regionComposition.regionObjects.get(objectKey);
...@@ -1549,7 +1523,7 @@ public class DvbSubtitlesParser { ...@@ -1549,7 +1523,7 @@ public class DvbSubtitlesParser {
} }
// fill the region if needed // fill the region if needed
if ((regionComposition.flags & REGION_FILL_FLAG )!= 0) { if ((regionComposition.flags & REGION_FILL_FLAG) != 0) {
int colour; int colour;
if (regionComposition.regionDepth == DVBSUB_RCS_BITDEPTH_8) { if (regionComposition.regionDepth == DVBSUB_RCS_BITDEPTH_8) {
colour = clut.clutEntries8bit[regionComposition.region8bitPixelCode].ARGB; colour = clut.clutEntries8bit[regionComposition.region8bitPixelCode].ARGB;
...@@ -1563,10 +1537,9 @@ public class DvbSubtitlesParser { ...@@ -1563,10 +1537,9 @@ public class DvbSubtitlesParser {
canvas.drawRect( canvas.drawRect(
baseHorizontalAddress, baseVerticalAddress, baseHorizontalAddress, baseVerticalAddress,
baseHorizontalAddress + regionComposition.regionWidth , baseHorizontalAddress + regionComposition.regionWidth,
baseVerticalAddress + regionComposition.regionHeight, baseVerticalAddress + regionComposition.regionHeight,
fillRegionPaint); fillRegionPaint);
} }
Bitmap cueBitmap = Bitmap.createBitmap(bitmap, Bitmap cueBitmap = Bitmap.createBitmap(bitmap,
...@@ -1577,14 +1550,14 @@ public class DvbSubtitlesParser { ...@@ -1577,14 +1550,14 @@ public class DvbSubtitlesParser {
(float) baseHorizontalAddress / subtitleService.displayDefinition.displayWidth, Cue.ANCHOR_TYPE_START, (float) baseHorizontalAddress / subtitleService.displayDefinition.displayWidth, Cue.ANCHOR_TYPE_START,
(float) baseVerticalAddress / subtitleService.displayDefinition.displayHeight, Cue.ANCHOR_TYPE_START, (float) baseVerticalAddress / subtitleService.displayDefinition.displayHeight, Cue.ANCHOR_TYPE_START,
(float) regionComposition.regionWidth / subtitleService.displayDefinition.displayWidth, (float) regionComposition.regionWidth / subtitleService.displayDefinition.displayWidth,
(float) subtitleService.displayDefinition.displayWidth / subtitleService.displayDefinition.displayHeight); (float) regionComposition.regionHeight / subtitleService.displayDefinition.displayHeight);
cueList.add(regionComposition.cue); cueList.add(regionComposition.cue);
} }
return cueList; return cueList;
} }
} else { } else {
Log.d(TAG,"Unexpected..."); Log.d(TAG, "Unexpected...");
} }
return null; return null;
} }
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.android.exoplayer2.text.dvbsubs; package com.google.android.exoplayer2.text.dvb;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.text.Cue; import com.google.android.exoplayer2.text.Cue;
...@@ -22,10 +22,13 @@ import com.google.android.exoplayer2.text.Subtitle; ...@@ -22,10 +22,13 @@ import com.google.android.exoplayer2.text.Subtitle;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
final class DvbSubsSubtitle implements Subtitle { /**
* A representation of a DVB subtitle.
*/
/* package */ final class DvbSubtitle implements Subtitle {
private final List<Cue> cues; private final List<Cue> cues;
public DvbSubsSubtitle(List<Cue> cues) { public DvbSubtitle(List<Cue> cues) {
if (cues == null) { if (cues == null) {
this.cues = Collections.emptyList(); this.cues = Collections.emptyList();
} else { } else {
......
/*
* 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.dvbsubs;
import com.google.android.exoplayer2.text.SimpleSubtitleDecoder;
import java.util.List;
public final class DvbSubsDecoder extends SimpleSubtitleDecoder {
private final String TAG = "DVBSubs Decoder";
private int subtitilingType;
private int subtitleCompositionPage;
private int subtitleAncillaryPage;
private String subtitleContainer;
private int flags = 0;
DvbSubtitlesParser parser;
public DvbSubsDecoder() {
super("dvbsubs");
parser = new DvbSubtitlesParser();
}
public DvbSubsDecoder(List<byte[]> initializationData) {
super("dvbsubs");
byte[] tempByteArray;
tempByteArray = initializationData.get(0);
subtitilingType = tempByteArray != null ? tempByteArray[0] & 0xFF: -1;
tempByteArray = initializationData.get(3);
if (tempByteArray != null ) {
subtitleContainer = new String(tempByteArray);
if (subtitleContainer.equals("mkv")) {
flags |= DvbSubtitlesParser.FLAG_PES_STRIPPED_DVBSUB;
}
}
if ((tempByteArray = initializationData.get(1)) != null) {
this.subtitleCompositionPage = ((tempByteArray[0] & 0xFF) << 8) | (tempByteArray[1] & 0xFF);
if ((tempByteArray = initializationData.get(2)) != null) {
this.subtitleAncillaryPage = ((tempByteArray[0] & 0xFF) << 8) | (tempByteArray[1] & 0xFF);
parser = new DvbSubtitlesParser(this.subtitleCompositionPage, this.subtitleAncillaryPage, flags);
}
} else {
parser = new DvbSubtitlesParser();
}
}
@Override
protected DvbSubsSubtitle decode(byte[] data, int length) {
return new DvbSubsSubtitle(parser.dvbSubsDecode(data, length));
}
}
\ No newline at end of file
...@@ -77,7 +77,7 @@ import com.google.android.exoplayer2.util.Util; ...@@ -77,7 +77,7 @@ import com.google.android.exoplayer2.util.Util;
@Cue.AnchorType @Cue.AnchorType
private int cuePositionAnchor; private int cuePositionAnchor;
private float cueSize; private float cueSize;
private float cueSar; private float cueBitmapHeight;
private boolean applyEmbeddedStyles; private boolean applyEmbeddedStyles;
private int foregroundColor; private int foregroundColor;
private int backgroundColor; private int backgroundColor;
...@@ -174,7 +174,7 @@ import com.google.android.exoplayer2.util.Util; ...@@ -174,7 +174,7 @@ import com.google.android.exoplayer2.util.Util;
&& this.cuePosition == cue.position && this.cuePosition == cue.position
&& Util.areEqual(this.cuePositionAnchor, cue.positionAnchor) && Util.areEqual(this.cuePositionAnchor, cue.positionAnchor)
&& this.cueSize == cue.size && this.cueSize == cue.size
&& this.cueSar == cue.sar && this.cueBitmapHeight == cue.bitmapHeight
&& this.applyEmbeddedStyles == applyEmbeddedStyles && this.applyEmbeddedStyles == applyEmbeddedStyles
&& this.foregroundColor == style.foregroundColor && this.foregroundColor == style.foregroundColor
&& this.backgroundColor == style.backgroundColor && this.backgroundColor == style.backgroundColor
...@@ -202,7 +202,7 @@ import com.google.android.exoplayer2.util.Util; ...@@ -202,7 +202,7 @@ import com.google.android.exoplayer2.util.Util;
this.cuePosition = cue.position; this.cuePosition = cue.position;
this.cuePositionAnchor = cue.positionAnchor; this.cuePositionAnchor = cue.positionAnchor;
this.cueSize = cue.size; this.cueSize = cue.size;
this.cueSar = cue.sar; this.cueBitmapHeight = cue.bitmapHeight;
this.applyEmbeddedStyles = applyEmbeddedStyles; this.applyEmbeddedStyles = applyEmbeddedStyles;
this.foregroundColor = style.foregroundColor; this.foregroundColor = style.foregroundColor;
this.backgroundColor = style.backgroundColor; this.backgroundColor = style.backgroundColor;
...@@ -315,7 +315,8 @@ import com.google.android.exoplayer2.util.Util; ...@@ -315,7 +315,8 @@ import com.google.android.exoplayer2.util.Util;
float anchorX = parentLeft + (parentWidth * cuePosition); float anchorX = parentLeft + (parentWidth * cuePosition);
float anchorY = parentTop + (parentHeight * cueLine); float anchorY = parentTop + (parentHeight * cueLine);
int width = Math.round(parentWidth * cueSize); int width = Math.round(parentWidth * cueSize);
int height = Math.round(width * ((float) cueBitmap.getHeight() / cueBitmap.getWidth()) / (((float) parentWidth / parentHeight) / cueSar)); int height = cueBitmapHeight != -1 ? Math.round(parentHeight * cueBitmapHeight)
: Math.round(width * ((float) cueBitmap.getHeight() / cueBitmap.getWidth()));
int x = Math.round(cueLineAnchor == Cue.ANCHOR_TYPE_END ? (anchorX - width) int x = Math.round(cueLineAnchor == Cue.ANCHOR_TYPE_END ? (anchorX - width)
: cueLineAnchor == Cue.ANCHOR_TYPE_MIDDLE ? (anchorX - (width / 2)) : anchorX); : cueLineAnchor == Cue.ANCHOR_TYPE_MIDDLE ? (anchorX - (width / 2)) : anchorX);
int y = Math.round(cuePositionAnchor == Cue.ANCHOR_TYPE_END ? (anchorY - height) int y = Math.round(cuePositionAnchor == Cue.ANCHOR_TYPE_END ? (anchorY - height)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment