From 5ce210e374ab4c0a078c9b3607c4d2b222e8043a Mon Sep 17 00:00:00 2001 From: olly Date: Tue, 19 Apr 2016 01:48:18 -0700 Subject: [PATCH] Propagate format information through RollingSampleBuffer. At this point the only reason preventing the chunk package from using RollingSampleBuffer directly, rather than DefaultTrackOutput, is that the latter maintains the largest parsed timestamp. This will be pushed inside the former in the next CL. Following that, splicing logic will also be pushed inside of RollingSampleBuffer, and HLS will be moved over to using a single RollingSampleBuffer per track, with the splicing done inline. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=120206658 --- .../exoplayer/chunk/BaseMediaChunk.java | 27 +-------- .../chunk/ChunkExtractorWrapper.java | 8 +-- .../exoplayer/chunk/ChunkSampleSource.java | 14 ++--- .../exoplayer/chunk/ContainerMediaChunk.java | 29 +-------- .../exoplayer/chunk/InitializationChunk.java | 13 +--- .../chunk/SingleSampleMediaChunk.java | 12 ++-- .../exoplayer/dash/DashChunkSource.java | 11 ++-- .../extractor/DefaultTrackOutput.java | 22 +++++-- .../extractor/ExtractorSampleSource.java | 6 +- .../extractor/RollingSampleBuffer.java | 59 +++++++++++++++++-- .../exoplayer/hls/HlsExtractorWrapper.java | 9 +-- 11 files changed, 98 insertions(+), 112 deletions(-) diff --git a/library/src/main/java/com/google/android/exoplayer/chunk/BaseMediaChunk.java b/library/src/main/java/com/google/android/exoplayer/chunk/BaseMediaChunk.java index 609eb9cb4e..3483ed68d5 100644 --- a/library/src/main/java/com/google/android/exoplayer/chunk/BaseMediaChunk.java +++ b/library/src/main/java/com/google/android/exoplayer/chunk/BaseMediaChunk.java @@ -28,13 +28,6 @@ import com.google.android.exoplayer.upstream.DataSpec; */ public abstract class BaseMediaChunk extends MediaChunk { - /** - * Whether {@link #getSampleFormat()} and {@link #getDrmInitData()} can be called at any time to - * obtain the chunk's sample format and drm initialization data. If false, these methods are only - * guaranteed to return correct data after the first sample data has been output from the chunk. - */ - public final boolean isSampleFormatFinal; - private DefaultTrackOutput trackOutput; private int firstSampleIndex; @@ -46,15 +39,10 @@ public abstract class BaseMediaChunk extends MediaChunk { * @param startTimeUs The start time of the media contained by the chunk, in microseconds. * @param endTimeUs The end time of the media contained by the chunk, in microseconds. * @param chunkIndex The index of the chunk. - * @param isSampleFormatFinal True if {@link #getSampleFormat()} and {@link #getDrmInitData()} can - * be called at any time to obtain the sample format and drm initialization data. False if - * these methods are only guaranteed to return correct data after the first sample data has - * been output from the chunk. */ public BaseMediaChunk(DataSource dataSource, DataSpec dataSpec, int trigger, Format format, - long startTimeUs, long endTimeUs, int chunkIndex, boolean isSampleFormatFinal) { + long startTimeUs, long endTimeUs, int chunkIndex) { super(dataSource, dataSpec, trigger, format, startTimeUs, endTimeUs, chunkIndex); - this.isSampleFormatFinal = isSampleFormatFinal; } /** @@ -76,21 +64,8 @@ public abstract class BaseMediaChunk extends MediaChunk { return firstSampleIndex; } - /** - * Gets the {@link Format} of the samples in the chunk. - *

- * See {@link #isSampleFormatFinal} for information about when this method is guaranteed to return - * correct data. - * - * @return The {@link Format} of the samples in the chunk. - */ - public abstract Format getSampleFormat(); - /** * Gets the {@link DrmInitData} corresponding to the chunk. - *

- * See {@link #isSampleFormatFinal} for information about when this method is guaranteed to return - * correct data. * * @return The {@link DrmInitData} corresponding to this chunk. */ diff --git a/library/src/main/java/com/google/android/exoplayer/chunk/ChunkExtractorWrapper.java b/library/src/main/java/com/google/android/exoplayer/chunk/ChunkExtractorWrapper.java index ee2ec5b0c9..63850a16bc 100644 --- a/library/src/main/java/com/google/android/exoplayer/chunk/ChunkExtractorWrapper.java +++ b/library/src/main/java/com/google/android/exoplayer/chunk/ChunkExtractorWrapper.java @@ -50,11 +50,6 @@ public final class ChunkExtractorWrapper implements ExtractorOutput, TrackOutput */ void drmInitData(DrmInitData drmInitData); - /** - * @see TrackOutput#format(Format) - */ - void format(Format format); - } private final Extractor extractor; @@ -132,8 +127,7 @@ public final class ChunkExtractorWrapper implements ExtractorOutput, TrackOutput @Override public void format(Format format) { - // Redirect the format to the metadata output. The track output doesn't need it. - metadataOutput.format(format); + trackOutput.format(format); } @Override diff --git a/library/src/main/java/com/google/android/exoplayer/chunk/ChunkSampleSource.java b/library/src/main/java/com/google/android/exoplayer/chunk/ChunkSampleSource.java index 3fbd9d781e..d79d8cb302 100644 --- a/library/src/main/java/com/google/android/exoplayer/chunk/ChunkSampleSource.java +++ b/library/src/main/java/com/google/android/exoplayer/chunk/ChunkSampleSource.java @@ -300,14 +300,12 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call downstreamFormat = currentChunk.format; } - if (haveSamples || currentChunk.isSampleFormatFinal) { - Format sampleFormat = currentChunk.getSampleFormat(); - if (!sampleFormat.equals(downstreamSampleFormat)) { - formatHolder.format = sampleFormat; - formatHolder.drmInitData = currentChunk.getDrmInitData(); - downstreamSampleFormat = sampleFormat; - return FORMAT_READ; - } + Format sampleFormat = sampleQueue.getDownstreamFormat(); + if (sampleFormat != null && !sampleFormat.equals(downstreamSampleFormat)) { + formatHolder.format = sampleFormat; + formatHolder.drmInitData = currentChunk.getDrmInitData(); + downstreamSampleFormat = sampleFormat; + return FORMAT_READ; } if (!haveSamples) { diff --git a/library/src/main/java/com/google/android/exoplayer/chunk/ContainerMediaChunk.java b/library/src/main/java/com/google/android/exoplayer/chunk/ContainerMediaChunk.java index 43be1784de..67d8da8d5f 100644 --- a/library/src/main/java/com/google/android/exoplayer/chunk/ContainerMediaChunk.java +++ b/library/src/main/java/com/google/android/exoplayer/chunk/ContainerMediaChunk.java @@ -60,11 +60,10 @@ public class ContainerMediaChunk extends BaseMediaChunk implements SingleTrackMe public ContainerMediaChunk(DataSource dataSource, DataSpec dataSpec, int trigger, Format format, long startTimeUs, long endTimeUs, int chunkIndex, long sampleOffsetUs, ChunkExtractorWrapper extractorWrapper, Format sampleFormat, DrmInitData drmInitData) { - super(dataSource, dataSpec, trigger, format, startTimeUs, endTimeUs, chunkIndex, - sampleFormat != null); + super(dataSource, dataSpec, trigger, format, startTimeUs, endTimeUs, chunkIndex); this.extractorWrapper = extractorWrapper; this.sampleOffsetUs = sampleOffsetUs; - this.sampleFormat = getAdjustedSampleFormat(sampleFormat, sampleOffsetUs); + this.sampleFormat = sampleFormat; this.drmInitData = drmInitData; } @@ -73,11 +72,6 @@ public class ContainerMediaChunk extends BaseMediaChunk implements SingleTrackMe return bytesLoaded; } - @Override - public final Format getSampleFormat() { - return sampleFormat; - } - @Override public final DrmInitData getDrmInitData() { return drmInitData; @@ -95,11 +89,6 @@ public class ContainerMediaChunk extends BaseMediaChunk implements SingleTrackMe this.drmInitData = drmInitData; } - @Override - public final void format(Format format) { - this.sampleFormat = getAdjustedSampleFormat(format, sampleOffsetUs); - } - // Loadable implementation. @Override @@ -123,7 +112,7 @@ public class ContainerMediaChunk extends BaseMediaChunk implements SingleTrackMe if (bytesLoaded == 0) { // Set the target to ourselves. DefaultTrackOutput trackOutput = getTrackOutput(); - trackOutput.setSampleOffsetUs(sampleOffsetUs); + trackOutput.formatWithOffset(sampleFormat, sampleOffsetUs); extractorWrapper.init(this, trackOutput); } // Load and parse the sample data. @@ -140,16 +129,4 @@ public class ContainerMediaChunk extends BaseMediaChunk implements SingleTrackMe } } - // Private methods. - - private static Format getAdjustedSampleFormat(Format format, long sampleOffsetUs) { - if (format == null) { - return null; - } - if (sampleOffsetUs != 0 && format.subsampleOffsetUs != Format.OFFSET_SAMPLE_RELATIVE) { - format = format.copyWithSubsampleOffsetUs(format.subsampleOffsetUs + sampleOffsetUs); - } - return format; - } - } diff --git a/library/src/main/java/com/google/android/exoplayer/chunk/InitializationChunk.java b/library/src/main/java/com/google/android/exoplayer/chunk/InitializationChunk.java index 63f66e2a69..303419617d 100644 --- a/library/src/main/java/com/google/android/exoplayer/chunk/InitializationChunk.java +++ b/library/src/main/java/com/google/android/exoplayer/chunk/InitializationChunk.java @@ -86,15 +86,6 @@ public final class InitializationChunk extends Chunk implements SingleTrackMetad return drmInitData; } - /** - * True if a {@link SeekMap} was parsed from the chunk. False otherwise. - *

- * Should be called after loading has completed. - */ - public boolean hasSeekMap() { - return seekMap != null; - } - /** * Returns a {@link SeekMap} parsed from the chunk, or null. *

@@ -116,13 +107,13 @@ public final class InitializationChunk extends Chunk implements SingleTrackMetad this.drmInitData = drmInitData; } + // TrackOutput implementation. + @Override public void format(Format format) { this.sampleFormat = format; } - // TrackOutput implementation. - @Override public int sampleData(ExtractorInput input, int length, boolean allowEndOfInput) throws IOException, InterruptedException { diff --git a/library/src/main/java/com/google/android/exoplayer/chunk/SingleSampleMediaChunk.java b/library/src/main/java/com/google/android/exoplayer/chunk/SingleSampleMediaChunk.java index c93eecb722..82a3dc8696 100644 --- a/library/src/main/java/com/google/android/exoplayer/chunk/SingleSampleMediaChunk.java +++ b/library/src/main/java/com/google/android/exoplayer/chunk/SingleSampleMediaChunk.java @@ -19,8 +19,8 @@ import com.google.android.exoplayer.C; import com.google.android.exoplayer.Format; import com.google.android.exoplayer.drm.DrmInitData; import com.google.android.exoplayer.extractor.DefaultExtractorInput; +import com.google.android.exoplayer.extractor.DefaultTrackOutput; import com.google.android.exoplayer.extractor.ExtractorInput; -import com.google.android.exoplayer.extractor.TrackOutput; import com.google.android.exoplayer.upstream.DataSource; import com.google.android.exoplayer.upstream.DataSpec; import com.google.android.exoplayer.util.Util; @@ -53,7 +53,7 @@ public final class SingleSampleMediaChunk extends BaseMediaChunk { public SingleSampleMediaChunk(DataSource dataSource, DataSpec dataSpec, int trigger, Format format, long startTimeUs, long endTimeUs, int chunkIndex, Format sampleFormat, DrmInitData sampleDrmInitData) { - super(dataSource, dataSpec, trigger, format, startTimeUs, endTimeUs, chunkIndex, true); + super(dataSource, dataSpec, trigger, format, startTimeUs, endTimeUs, chunkIndex); this.sampleFormat = sampleFormat; this.sampleDrmInitData = sampleDrmInitData; } @@ -63,11 +63,6 @@ public final class SingleSampleMediaChunk extends BaseMediaChunk { return bytesLoaded; } - @Override - public Format getSampleFormat() { - return sampleFormat; - } - @Override public DrmInitData getDrmInitData() { return sampleDrmInitData; @@ -96,7 +91,8 @@ public final class SingleSampleMediaChunk extends BaseMediaChunk { length += bytesLoaded; } ExtractorInput extractorInput = new DefaultExtractorInput(dataSource, bytesLoaded, length); - TrackOutput trackOutput = getTrackOutput(); + DefaultTrackOutput trackOutput = getTrackOutput(); + trackOutput.formatWithOffset(sampleFormat, 0); // Load the sample data. int result = 0; while (result != C.RESULT_END_OF_INPUT) { 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 7a7fff2f91..99c44ca554 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 @@ -38,6 +38,7 @@ import com.google.android.exoplayer.dash.mpd.RangedUri; import com.google.android.exoplayer.dash.mpd.Representation; import com.google.android.exoplayer.drm.DrmInitData; import com.google.android.exoplayer.extractor.ChunkIndex; +import com.google.android.exoplayer.extractor.SeekMap; import com.google.android.exoplayer.extractor.mkv.MatroskaExtractor; import com.google.android.exoplayer.extractor.mp4.FragmentedMp4Extractor; import com.google.android.exoplayer.upstream.DataSource; @@ -296,10 +297,12 @@ public class DashChunkSource implements ChunkSource { // The null check avoids overwriting an index obtained from the manifest with one obtained // from the stream. If the manifest defines an index then the stream shouldn't, but in cases // where it does we should ignore it. - if (representationHolder.segmentIndex == null && initializationChunk.hasSeekMap()) { - representationHolder.segmentIndex = new DashWrappingSegmentIndex( - (ChunkIndex) initializationChunk.getSeekMap(), - initializationChunk.dataSpec.uri.toString()); + if (representationHolder.segmentIndex == null) { + SeekMap seekMap = initializationChunk.getSeekMap(); + if (seekMap != null) { + representationHolder.segmentIndex = new DashWrappingSegmentIndex((ChunkIndex) seekMap, + initializationChunk.dataSpec.uri.toString()); + } } // The null check avoids overwriting drmInitData obtained from the manifest with drmInitData // obtained from the stream, as per DASH IF Interoperability Recommendations V3.0, 7.5.3. diff --git a/library/src/main/java/com/google/android/exoplayer/extractor/DefaultTrackOutput.java b/library/src/main/java/com/google/android/exoplayer/extractor/DefaultTrackOutput.java index a7d1a8f86c..c3ef28c4d2 100644 --- a/library/src/main/java/com/google/android/exoplayer/extractor/DefaultTrackOutput.java +++ b/library/src/main/java/com/google/android/exoplayer/extractor/DefaultTrackOutput.java @@ -92,12 +92,19 @@ public final class DefaultTrackOutput implements TrackOutput { } /** - * The format most recently received by the output, or null if a format has yet to be received. + * Returns the current upstream {@link Format}. */ - public Format getFormat() { + public Format getUpstreamFormat() { return rollingBuffer.getUpstreamFormat(); } + /** + * Returns the current downstream {@link Format}. + */ + public Format getDownstreamFormat() { + return rollingBuffer.getDownstreamFormat(); + } + /** * The largest timestamp of any sample received by the output, or {@link Long#MIN_VALUE} if a * sample has yet to be received. @@ -210,13 +217,16 @@ public final class DefaultTrackOutput implements TrackOutput { // Called by the loading thread. /** - * Sets an offset that will be added to the timestamps passed to - * {@link #sampleMetadata(long, int, int, int, byte[])}. + * Like {@link #format(Format)}, but with an offset that will be added to the timestamps of + * samples subsequently queued to the buffer. The offset is also used to adjust + * {@link Format#subsampleOffsetUs} for both the {@link Format} passed and those subsequently + * passed to {@link #format(Format)}. * + * @param format The format. * @param sampleOffsetUs The offset in microseconds. */ - public void setSampleOffsetUs(long sampleOffsetUs) { - rollingBuffer.setSampleOffsetUs(sampleOffsetUs); + public void formatWithOffset(Format format, long sampleOffsetUs) { + rollingBuffer.formatWithOffset(format, sampleOffsetUs); } @Override diff --git a/library/src/main/java/com/google/android/exoplayer/extractor/ExtractorSampleSource.java b/library/src/main/java/com/google/android/exoplayer/extractor/ExtractorSampleSource.java index 4f415ce85e..378917e5de 100644 --- a/library/src/main/java/com/google/android/exoplayer/extractor/ExtractorSampleSource.java +++ b/library/src/main/java/com/google/android/exoplayer/extractor/ExtractorSampleSource.java @@ -343,7 +343,7 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu pendingMediaFormat = new boolean[trackCount]; durationUs = seekMap.getDurationUs(); for (int i = 0; i < trackCount; i++) { - trackArray[i] = new TrackGroup(sampleQueues.valueAt(i).getFormat()); + trackArray[i] = new TrackGroup(sampleQueues.valueAt(i).getUpstreamFormat()); } tracks = new TrackGroupArray(trackArray); if (minLoadableRetryCount == MIN_RETRY_COUNT_DEFAULT_FOR_MEDIA && !seekMap.isSeekable() @@ -476,7 +476,7 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu DefaultTrackOutput sampleQueue = sampleQueues.valueAt(track); if (pendingMediaFormat[track]) { - formatHolder.format = sampleQueue.getFormat(); + formatHolder.format = sampleQueue.getUpstreamFormat(); formatHolder.drmInitData = drmInitData; pendingMediaFormat[track] = false; return TrackStream.FORMAT_READ; @@ -649,7 +649,7 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu private boolean haveFormatsForAllTracks() { for (int i = 0; i < sampleQueues.size(); i++) { - if (sampleQueues.valueAt(i).getFormat() == null) { + if (sampleQueues.valueAt(i).getUpstreamFormat() == null) { return false; } } diff --git a/library/src/main/java/com/google/android/exoplayer/extractor/RollingSampleBuffer.java b/library/src/main/java/com/google/android/exoplayer/extractor/RollingSampleBuffer.java index 2c0786cfb1..2ac38e66d6 100644 --- a/library/src/main/java/com/google/android/exoplayer/extractor/RollingSampleBuffer.java +++ b/library/src/main/java/com/google/android/exoplayer/extractor/RollingSampleBuffer.java @@ -137,12 +137,20 @@ import java.util.concurrent.LinkedBlockingDeque; } /** - * Returns the current upstream format. + * Returns the current upstream {@link Format}. */ public Format getUpstreamFormat() { return upstreamFormat; } + /** + * Returns the current downstream {@link Format}. + */ + public Format getDownstreamFormat() { + Format nextSampleFormat = infoQueue.peekFormat(); + return nextSampleFormat != null ? nextSampleFormat : upstreamFormat; + } + /** * Fills {@code buffer} with information about the current sample, but does not write its data. *

@@ -357,17 +365,22 @@ import java.util.concurrent.LinkedBlockingDeque; // Called by the loading thread. /** - * Sets an offset that will be added to the timestamps of subsequently queued samples. + * Like {@link #format(Format)}, but with an offset that will be added to the timestamps of + * samples subsequently queued to the buffer. The offset is also used to adjust + * {@link Format#subsampleOffsetUs} for both the {@link Format} passed and those subsequently + * passed to {@link #format(Format)}. * + * @param format The format. * @param sampleOffsetUs The timestamp offset in microseconds. */ - public void setSampleOffsetUs(long sampleOffsetUs) { + public void formatWithOffset(Format format, long sampleOffsetUs) { this.sampleOffsetUs = sampleOffsetUs; + upstreamFormat = getAdjustedSampleFormat(format, sampleOffsetUs); } @Override public void format(Format format) { - upstreamFormat = format; + upstreamFormat = getAdjustedSampleFormat(format, sampleOffsetUs); } @Override @@ -403,7 +416,7 @@ import java.util.concurrent.LinkedBlockingDeque; public void sampleMetadata(long timeUs, int flags, int size, int offset, byte[] encryptionKey) { timeUs += sampleOffsetUs; long absoluteOffset = totalBytesWritten - size - offset; - infoQueue.commitSample(timeUs, flags, absoluteOffset, size, encryptionKey); + infoQueue.commitSample(timeUs, flags, absoluteOffset, size, encryptionKey, upstreamFormat); } /** @@ -419,6 +432,23 @@ import java.util.concurrent.LinkedBlockingDeque; return Math.min(length, allocationLength - lastAllocationOffset); } + /** + * Adjusts a {@link Format} to incorporate a sample offset into {@link Format#subsampleOffsetUs}. + * + * @param format The {@link Format} to adjust. + * @param sampleOffsetUs The offset to apply. + * @return The adjusted {@link Format}. + */ + private static Format getAdjustedSampleFormat(Format format, long sampleOffsetUs) { + if (format == null) { + return null; + } + if (sampleOffsetUs != 0 && format.subsampleOffsetUs != Format.OFFSET_SAMPLE_RELATIVE) { + format = format.copyWithSubsampleOffsetUs(format.subsampleOffsetUs + sampleOffsetUs); + } + return format; + } + /** * Holds information about the samples in the rolling buffer. */ @@ -433,6 +463,7 @@ import java.util.concurrent.LinkedBlockingDeque; private int[] flags; private long[] timesUs; private byte[][] encryptionKeys; + private Format[] formats; private int queueSize; private int absoluteReadIndex; @@ -446,6 +477,7 @@ import java.util.concurrent.LinkedBlockingDeque; flags = new int[capacity]; sizes = new int[capacity]; encryptionKeys = new byte[capacity][]; + formats = new Format[capacity]; } // Called by the consuming thread, but only when there is no loading thread. @@ -500,6 +532,16 @@ import java.util.concurrent.LinkedBlockingDeque; return absoluteReadIndex; } + /** + * Returns the {@link Format} of the next sample, or null of the queue is empty. + */ + public synchronized Format peekFormat() { + if (queueSize == 0) { + return null; + } + return formats[relativeReadIndex]; + } + /** * Fills {@code buffer} with information about the current sample, but does not write its data. * The absolute position of the sample's data in the rolling buffer is stored in @@ -609,12 +651,13 @@ import java.util.concurrent.LinkedBlockingDeque; // Called by the loading thread. public synchronized void commitSample(long timeUs, int sampleFlags, long offset, int size, - byte[] encryptionKey) { + byte[] encryptionKey, Format format) { timesUs[relativeWriteIndex] = timeUs; offsets[relativeWriteIndex] = offset; sizes[relativeWriteIndex] = size; flags[relativeWriteIndex] = sampleFlags; encryptionKeys[relativeWriteIndex] = encryptionKey; + formats[relativeWriteIndex] = format; // Increment the write index. queueSize++; if (queueSize == capacity) { @@ -625,23 +668,27 @@ import java.util.concurrent.LinkedBlockingDeque; int[] newFlags = new int[newCapacity]; int[] newSizes = new int[newCapacity]; byte[][] newEncryptionKeys = new byte[newCapacity][]; + Format[] newFormats = new Format[newCapacity]; int beforeWrap = capacity - relativeReadIndex; System.arraycopy(offsets, relativeReadIndex, newOffsets, 0, beforeWrap); System.arraycopy(timesUs, relativeReadIndex, newTimesUs, 0, beforeWrap); System.arraycopy(flags, relativeReadIndex, newFlags, 0, beforeWrap); System.arraycopy(sizes, relativeReadIndex, newSizes, 0, beforeWrap); System.arraycopy(encryptionKeys, relativeReadIndex, newEncryptionKeys, 0, beforeWrap); + System.arraycopy(formats, relativeReadIndex, newFormats, 0, beforeWrap); int afterWrap = relativeReadIndex; System.arraycopy(offsets, 0, newOffsets, beforeWrap, afterWrap); System.arraycopy(timesUs, 0, newTimesUs, beforeWrap, afterWrap); System.arraycopy(flags, 0, newFlags, beforeWrap, afterWrap); System.arraycopy(sizes, 0, newSizes, beforeWrap, afterWrap); System.arraycopy(encryptionKeys, 0, newEncryptionKeys, beforeWrap, afterWrap); + System.arraycopy(formats, 0, newFormats, beforeWrap, afterWrap); offsets = newOffsets; timesUs = newTimesUs; flags = newFlags; sizes = newSizes; encryptionKeys = newEncryptionKeys; + formats = newFormats; relativeReadIndex = 0; relativeWriteIndex = capacity; queueSize = capacity; diff --git a/library/src/main/java/com/google/android/exoplayer/hls/HlsExtractorWrapper.java b/library/src/main/java/com/google/android/exoplayer/hls/HlsExtractorWrapper.java index 1099bc860e..cdcca2771f 100644 --- a/library/src/main/java/com/google/android/exoplayer/hls/HlsExtractorWrapper.java +++ b/library/src/main/java/com/google/android/exoplayer/hls/HlsExtractorWrapper.java @@ -44,7 +44,6 @@ public final class HlsExtractorWrapper implements ExtractorOutput { private final SparseArray sampleQueues; private final boolean shouldSpliceIn; - private Format[] sampleFormats; private Allocator allocator; private volatile boolean tracksBuilt; @@ -81,15 +80,11 @@ public final class HlsExtractorWrapper implements ExtractorOutput { public boolean isPrepared() { if (!prepared && tracksBuilt) { for (int i = 0; i < sampleQueues.size(); i++) { - if (sampleQueues.valueAt(i).getFormat() == null) { + if (sampleQueues.valueAt(i).getUpstreamFormat() == null) { return false; } } prepared = true; - sampleFormats = new Format[sampleQueues.size()]; - for (int i = 0; i < sampleFormats.length; i++) { - sampleFormats[i] = sampleQueues.valueAt(i).getFormat(); - } } return prepared; } @@ -173,7 +168,7 @@ public final class HlsExtractorWrapper implements ExtractorOutput { */ public Format getSampleFormat(int track) { Assertions.checkState(isPrepared()); - return sampleFormats[track]; + return sampleQueues.valueAt(track).getUpstreamFormat(); } /**