Handle raw TTML in DASH correctly.

This commit is contained in:
Oliver Woodman 2015-09-07 13:55:35 +01:00
parent 0c968703c8
commit 4104a8def9

View file

@ -64,7 +64,7 @@ import java.util.List;
/** /**
* An {@link ChunkSource} for DASH streams. * An {@link ChunkSource} for DASH streams.
* <p> * <p>
* This implementation currently supports fMP4, webm, and webvtt. * This implementation currently supports fMP4, webm, webvtt and ttml.
* <p> * <p>
* This implementation makes the following assumptions about multi-period manifests: * This implementation makes the following assumptions about multi-period manifests:
* <ol> * <ol>
@ -600,10 +600,14 @@ public class DashChunkSource implements ChunkSource, Output {
return mimeType; return mimeType;
} }
private static boolean mimeTypeIsWebm(String mimeType) { /* package */ static boolean mimeTypeIsWebm(String mimeType) {
return mimeType.startsWith(MimeTypes.VIDEO_WEBM) || mimeType.startsWith(MimeTypes.AUDIO_WEBM); return mimeType.startsWith(MimeTypes.VIDEO_WEBM) || mimeType.startsWith(MimeTypes.AUDIO_WEBM);
} }
/* package */ static boolean mimeTypeIsRawText(String mimeType) {
return MimeTypes.TEXT_VTT.equals(mimeType) || MimeTypes.APPLICATION_TTML.equals(mimeType);
}
private Chunk newInitializationChunk(RangedUri initializationUri, RangedUri indexUri, private Chunk newInitializationChunk(RangedUri initializationUri, RangedUri indexUri,
Representation representation, ChunkExtractorWrapper extractor, DataSource dataSource, Representation representation, ChunkExtractorWrapper extractor, DataSource dataSource,
int manifestIndex, int trigger) { int manifestIndex, int trigger) {
@ -627,6 +631,7 @@ public class DashChunkSource implements ChunkSource, Output {
private Chunk newMediaChunk(PeriodHolder periodHolder, RepresentationHolder representationHolder, private Chunk newMediaChunk(PeriodHolder periodHolder, RepresentationHolder representationHolder,
DataSource dataSource, MediaFormat mediaFormat, int segmentNum, int trigger) { DataSource dataSource, MediaFormat mediaFormat, int segmentNum, int trigger) {
Representation representation = representationHolder.representation; Representation representation = representationHolder.representation;
Format format = representation.format;
long startTimeUs = representationHolder.getSegmentStartTimeUs(segmentNum); long startTimeUs = representationHolder.getSegmentStartTimeUs(segmentNum);
long endTimeUs = representationHolder.getSegmentEndTimeUs(segmentNum); long endTimeUs = representationHolder.getSegmentEndTimeUs(segmentNum);
@ -639,18 +644,17 @@ public class DashChunkSource implements ChunkSource, Output {
representation.getCacheKey()); representation.getCacheKey());
long sampleOffsetUs = periodHolder.startTimeUs - representation.presentationTimeOffsetUs; long sampleOffsetUs = periodHolder.startTimeUs - representation.presentationTimeOffsetUs;
if (representation.format.mimeType.equals(MimeTypes.TEXT_VTT)) { if (mimeTypeIsRawText(format.mimeType)) {
return new SingleSampleMediaChunk(dataSource, dataSpec, Chunk.TRIGGER_INITIAL, return new SingleSampleMediaChunk(dataSource, dataSpec, Chunk.TRIGGER_INITIAL, format,
representation.format, startTimeUs, endTimeUs, segmentNum, isLastSegment, startTimeUs, endTimeUs, segmentNum, isLastSegment,
MediaFormat.createTextFormat(MimeTypes.TEXT_VTT, MediaFormat.NO_VALUE, MediaFormat.createTextFormat(format.mimeType, MediaFormat.NO_VALUE, format.language),
representation.format.language), null, periodHolder.localIndex); null, periodHolder.localIndex);
} else { } else {
boolean isMediaFormatFinal = (mediaFormat != null); boolean isMediaFormatFinal = (mediaFormat != null);
return new ContainerMediaChunk(dataSource, dataSpec, trigger, representation.format, return new ContainerMediaChunk(dataSource, dataSpec, trigger, format, startTimeUs, endTimeUs,
startTimeUs, endTimeUs, segmentNum, isLastSegment, sampleOffsetUs, segmentNum, isLastSegment, sampleOffsetUs, representationHolder.extractorWrapper,
representationHolder.extractorWrapper, mediaFormat, enabledTrack.adaptiveMaxWidth, mediaFormat, enabledTrack.adaptiveMaxWidth, enabledTrack.adaptiveMaxHeight,
enabledTrack.adaptiveMaxHeight, periodHolder.drmInitData, isMediaFormatFinal, periodHolder.drmInitData, isMediaFormatFinal, periodHolder.localIndex);
periodHolder.localIndex);
} }
} }
@ -811,9 +815,9 @@ public class DashChunkSource implements ChunkSource, Output {
this.periodStartTimeUs = periodStartTimeUs; this.periodStartTimeUs = periodStartTimeUs;
this.periodDurationUs = periodDurationUs; this.periodDurationUs = periodDurationUs;
this.representation = representation; this.representation = representation;
extractorWrapper = MimeTypes.TEXT_VTT.equals(representation.format.mimeType) ? null String mimeType = representation.format.mimeType;
: new ChunkExtractorWrapper(mimeTypeIsWebm(representation.format.mimeType) extractorWrapper = mimeTypeIsRawText(mimeType) ? null : new ChunkExtractorWrapper(
? new WebmExtractor() : new FragmentedMp4Extractor()); mimeTypeIsWebm(mimeType) ? new WebmExtractor() : new FragmentedMp4Extractor());
segmentIndex = representation.getIndex(); segmentIndex = representation.getIndex();
} }