From 937675d1dbeb8fcaf31f2e7c67fe576115c204cc Mon Sep 17 00:00:00 2001 From: Sergio Moreno Mozota Date: Thu, 23 Mar 2017 08:54:07 +0100 Subject: [PATCH] Add DVB sustitles support to the TsExtractor --- .../ts/DefaultTsPayloadReaderFactory.java | 2 + .../extractor/ts/DvbSubtitlesReader.java | 89 +++++++++++++++++++ .../exoplayer2/extractor/ts/TsExtractor.java | 6 ++ 3 files changed, 97 insertions(+) create mode 100644 library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/DvbSubtitlesReader.java diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/DefaultTsPayloadReaderFactory.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/DefaultTsPayloadReaderFactory.java index e8b664d5ab..d2b0acca85 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/DefaultTsPayloadReaderFactory.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/DefaultTsPayloadReaderFactory.java @@ -109,6 +109,8 @@ public final class DefaultTsPayloadReaderFactory implements TsPayloadReader.Fact ? 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; } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/DvbSubtitlesReader.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/DvbSubtitlesReader.java new file mode 100644 index 0000000000..0e5931e9fe --- /dev/null +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/DvbSubtitlesReader.java @@ -0,0 +1,89 @@ +/* + * 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.List; + + +public class DvbSubtitlesReader implements ElementaryStreamReader { + + private static final String TAG= "DVBSubsReader"; + private final String language; + private List initializationData = new ArrayList<>(); + + private long sampleTimeUs; + private int totalBytesWritten; + private boolean writingSample; + + private TrackOutput output; + + public DvbSubtitlesReader(TsPayloadReader.EsInfo esInfo) { + // we only support one subtitle service per PID + this.language = esInfo.language; + this.initializationData.add(new byte[] {esInfo.descriptorBytes[5]}); // subtitle subtype + this.initializationData.add(new byte[] {esInfo.descriptorBytes[6], esInfo.descriptorBytes[7]}); // subtitle compose page + this.initializationData.add(new byte[] {esInfo.descriptorBytes[8], esInfo.descriptorBytes[9]}); // subtitle ancillary page + this.initializationData.add("mp2t".getBytes()); + } + + + @Override + public void seek() { + writingSample = false; + } + + @Override + public void createTracks(ExtractorOutput extractorOutput, TrackIdGenerator idGenerator) { + idGenerator.generateNewId(); + 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)); + } + + + @Override + public void packetStarted(long pesTimeUs, boolean dataAlignmentIndicator) { + if (!dataAlignmentIndicator) { + return; + } + writingSample = true; + sampleTimeUs = pesTimeUs; + totalBytesWritten = 0; + } + + @Override + public void packetFinished() { + output.sampleMetadata(sampleTimeUs, C.BUFFER_FLAG_KEY_FRAME, totalBytesWritten, 0, null); + writingSample = false; + } + + @Override + public void consume(ParsableByteArray data) { + if (writingSample) { + totalBytesWritten += data.bytesLeft(); + output.sampleData(data, data.bytesLeft()); + } + } +} \ No newline at end of file diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/TsExtractor.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/TsExtractor.java index 65b97c8a73..3c163541ac 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/TsExtractor.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/ts/TsExtractor.java @@ -92,6 +92,7 @@ public final class TsExtractor implements Extractor { 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. @@ -356,6 +357,7 @@ public final class TsExtractor implements Extractor { 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; @@ -498,6 +500,10 @@ public final class TsExtractor implements Extractor { } 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; + // we only support one subtitle service per PID + language = new String(data.data, data.getPosition(), 3).trim(); } // Skip unused bytes of current descriptor. data.skipBytes(positionOfNextDescriptor - data.getPosition());