Add DVB sustitles support to the TsExtractor

This commit is contained in:
Sergio Moreno Mozota 2017-03-23 08:54:07 +01:00
parent d8f61ad7e7
commit 937675d1db
3 changed files with 97 additions and 0 deletions

View File

@ -109,6 +109,8 @@ public final class DefaultTsPayloadReaderFactory implements TsPayloadReader.Fact
? null : new SectionReader(new SpliceInfoSectionReader()); ? null : new SectionReader(new SpliceInfoSectionReader());
case TsExtractor.TS_STREAM_TYPE_ID3: case TsExtractor.TS_STREAM_TYPE_ID3:
return new PesReader(new Id3Reader()); return new PesReader(new Id3Reader());
case TsExtractor.TS_STREAM_TYPE_DVBSUBS:
return new PesReader(new DvbSubtitlesReader(esInfo));
default: default:
return null; return null;
} }

View File

@ -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<byte[]> 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());
}
}
}

View File

@ -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_H265 = 0x24;
public static final int TS_STREAM_TYPE_ID3 = 0x15; 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_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_PACKET_SIZE = 188;
private static final int TS_SYNC_BYTE = 0x47; // First byte of each TS packet. 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_AC3 = 0x6A;
private static final int TS_PMT_DESC_EAC3 = 0x7A; 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_DTS = 0x7B;
private static final int TS_PMT_DESC_DVBSUBS = 0x59;
private final ParsableBitArray pmtScratch; private final ParsableBitArray pmtScratch;
private final int pid; private final int pid;
@ -498,6 +500,10 @@ public final class TsExtractor implements Extractor {
} else if (descriptorTag == TS_PMT_DESC_ISO639_LANG) { } else if (descriptorTag == TS_PMT_DESC_ISO639_LANG) {
language = new String(data.data, data.getPosition(), 3).trim(); language = new String(data.data, data.getPosition(), 3).trim();
// Audio type is ignored. // 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. // Skip unused bytes of current descriptor.
data.skipBytes(positionOfNextDescriptor - data.getPosition()); data.skipBytes(positionOfNextDescriptor - data.getPosition());