diff --git a/library/src/main/java/com/google/android/exoplayer/chunk/Mp4MediaChunk.java b/library/src/main/java/com/google/android/exoplayer/chunk/Mp4MediaChunk.java index a4d05cacd7..e39c53ebff 100644 --- a/library/src/main/java/com/google/android/exoplayer/chunk/Mp4MediaChunk.java +++ b/library/src/main/java/com/google/android/exoplayer/chunk/Mp4MediaChunk.java @@ -40,6 +40,17 @@ public final class Mp4MediaChunk extends MediaChunk { private MediaFormat mediaFormat; private Map psshInfo; + /** + * @deprecated Use the other constructor, passing null as {@code psshInfo}. + */ + @Deprecated + public Mp4MediaChunk(DataSource dataSource, DataSpec dataSpec, Format format, + int trigger, long startTimeUs, long endTimeUs, int nextChunkIndex, + Extractor extractor, boolean maybeSelfContained, long sampleOffsetUs) { + this(dataSource, dataSpec, format, trigger, startTimeUs, endTimeUs, nextChunkIndex, + extractor, null, maybeSelfContained, sampleOffsetUs); + } + /** * @param dataSource A {@link DataSource} for loading the data. * @param dataSpec Defines the data to be loaded. @@ -49,6 +60,8 @@ public final class Mp4MediaChunk extends MediaChunk { * @param endTimeUs The end time of the media contained by the chunk, in microseconds. * @param nextChunkIndex The index of the next chunk, or -1 if this is the last chunk. * @param extractor The extractor that will be used to extract the samples. + * @param psshInfo Pssh data. May be null if pssh data is present within the stream, meaning it + * can be obtained directly from {@code extractor}, or if no pssh data is required. * @param maybeSelfContained Set to true if this chunk might be self contained, meaning it might * contain a moov atom defining the media format of the chunk. This parameter can always be * safely set to true. Setting to false where the chunk is known to not be self contained may @@ -56,12 +69,13 @@ public final class Mp4MediaChunk extends MediaChunk { * @param sampleOffsetUs An offset to subtract from the sample timestamps parsed by the extractor. */ public Mp4MediaChunk(DataSource dataSource, DataSpec dataSpec, Format format, - int trigger, long startTimeUs, long endTimeUs, int nextChunkIndex, - Extractor extractor, boolean maybeSelfContained, long sampleOffsetUs) { + int trigger, long startTimeUs, long endTimeUs, int nextChunkIndex, Extractor extractor, + Map psshInfo, boolean maybeSelfContained, long sampleOffsetUs) { super(dataSource, dataSpec, format, trigger, startTimeUs, endTimeUs, nextChunkIndex); this.extractor = extractor; this.maybeSelfContained = maybeSelfContained; this.sampleOffsetUs = sampleOffsetUs; + this.psshInfo = psshInfo; } @Override @@ -97,7 +111,10 @@ public final class Mp4MediaChunk extends MediaChunk { } if (prepared) { mediaFormat = extractor.getFormat(); - psshInfo = extractor.getPsshInfo(); + Map extractorPsshInfo = extractor.getPsshInfo(); + if (extractorPsshInfo != null) { + psshInfo = extractorPsshInfo; + } } } return prepared; diff --git a/library/src/main/java/com/google/android/exoplayer/dash/DashChunkSource.java b/library/src/main/java/com/google/android/exoplayer/dash/DashChunkSource.java index 9bcb1aa3b8..d0c123bdc9 100644 --- a/library/src/main/java/com/google/android/exoplayer/dash/DashChunkSource.java +++ b/library/src/main/java/com/google/android/exoplayer/dash/DashChunkSource.java @@ -438,7 +438,7 @@ public class DashChunkSource implements ChunkSource { startTimeUs, endTimeUs, nextAbsoluteSegmentNum, null, representationHolder.vttHeader); } else { return new Mp4MediaChunk(dataSource, dataSpec, representation.format, trigger, startTimeUs, - endTimeUs, nextAbsoluteSegmentNum, representationHolder.extractor, false, + endTimeUs, nextAbsoluteSegmentNum, representationHolder.extractor, null, false, presentationTimeOffsetUs); } } diff --git a/library/src/main/java/com/google/android/exoplayer/parser/mp4/FragmentedMp4Extractor.java b/library/src/main/java/com/google/android/exoplayer/parser/mp4/FragmentedMp4Extractor.java index 9950aecd2a..34f0404083 100644 --- a/library/src/main/java/com/google/android/exoplayer/parser/mp4/FragmentedMp4Extractor.java +++ b/library/src/main/java/com/google/android/exoplayer/parser/mp4/FragmentedMp4Extractor.java @@ -189,20 +189,6 @@ public final class FragmentedMp4Extractor implements Extractor { this.track = track; } - /** - * Sideloads pssh information into the extractor, so that it can be read through - * {@link #getPsshInfo()}. - * - * @param uuid The UUID of the scheme for which information is being sideloaded. - * @param data The corresponding data. - */ - public void putPsshInfo(UUID uuid, byte[] data) { - // TODO: This is for SmoothStreaming. Consider using something other than - // FragmentedMp4Extractor.getPsshInfo to obtain the pssh data for that use case, so that we can - // remove this method. - psshData.put(uuid, data); - } - @Override public Map getPsshInfo() { return psshData.isEmpty() ? null : psshData; diff --git a/library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingChunkSource.java b/library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingChunkSource.java index 2b676e6b52..936fdf824d 100644 --- a/library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingChunkSource.java +++ b/library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingChunkSource.java @@ -48,6 +48,8 @@ import java.io.IOException; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.UUID; /** * An {@link ChunkSource} for SmoothStreaming. @@ -69,6 +71,7 @@ public class SmoothStreamingChunkSource implements ChunkSource { private final int maxHeight; private final SparseArray extractors; + private final Map psshInfo; private final SmoothStreamingFormat[] formats; private SmoothStreamingManifest currentManifest; @@ -140,6 +143,9 @@ public class SmoothStreamingChunkSource implements ChunkSource { byte[] keyId = getKeyId(protectionElement.data); trackEncryptionBoxes = new TrackEncryptionBox[1]; trackEncryptionBoxes[0] = new TrackEncryptionBox(true, INITIALIZATION_VECTOR_SIZE, keyId); + psshInfo = Collections.singletonMap(protectionElement.uuid, protectionElement.data); + } else { + psshInfo = null; } int trackCount = trackIndices != null ? trackIndices.length : streamElement.tracks.length; @@ -163,9 +169,6 @@ public class SmoothStreamingChunkSource implements ChunkSource { FragmentedMp4Extractor.WORKAROUND_EVERY_VIDEO_FRAME_IS_SYNC_FRAME); extractor.setTrack(new Track(trackIndex, trackType, streamElement.timescale, mediaFormat, trackEncryptionBoxes)); - if (protectionElement != null) { - extractor.putPsshInfo(protectionElement.uuid, protectionElement.data); - } extractors.put(trackIndex, extractor); } this.maxHeight = maxHeight; @@ -296,8 +299,8 @@ public class SmoothStreamingChunkSource implements ChunkSource { Uri uri = streamElement.buildRequestUri(selectedFormat.trackIndex, chunkIndex); Chunk mediaChunk = newMediaChunk(selectedFormat, uri, null, - extractors.get(Integer.parseInt(selectedFormat.id)), dataSource, currentAbsoluteChunkIndex, - isLastChunk, chunkStartTimeUs, nextChunkStartTimeUs, 0); + extractors.get(Integer.parseInt(selectedFormat.id)), psshInfo, dataSource, + currentAbsoluteChunkIndex, isLastChunk, chunkStartTimeUs, nextChunkStartTimeUs, 0); out.chunk = mediaChunk; } @@ -361,7 +364,7 @@ public class SmoothStreamingChunkSource implements ChunkSource { } private static MediaChunk newMediaChunk(Format formatInfo, Uri uri, String cacheKey, - Extractor extractor, DataSource dataSource, int chunkIndex, + Extractor extractor, Map psshInfo, DataSource dataSource, int chunkIndex, boolean isLast, long chunkStartTimeUs, long nextChunkStartTimeUs, int trigger) { int nextChunkIndex = isLast ? -1 : chunkIndex + 1; long nextStartTimeUs = isLast ? -1 : nextChunkStartTimeUs; @@ -370,7 +373,7 @@ public class SmoothStreamingChunkSource implements ChunkSource { // In SmoothStreaming each chunk contains sample timestamps relative to the start of the chunk. // To convert them the absolute timestamps, we need to set sampleOffsetUs to -chunkStartTimeUs. return new Mp4MediaChunk(dataSource, dataSpec, formatInfo, trigger, chunkStartTimeUs, - nextStartTimeUs, nextChunkIndex, extractor, false, -chunkStartTimeUs); + nextStartTimeUs, nextChunkIndex, extractor, psshInfo, false, -chunkStartTimeUs); } private static byte[] getKeyId(byte[] initData) {