diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/DummyTrackOutput.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/DummyTrackOutput.java
index c023b0de95..9eaf0f7ef7 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/DummyTrackOutput.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/DummyTrackOutput.java
@@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.extractor;
+import android.support.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.util.ParsableByteArray;
@@ -50,9 +51,12 @@ public final class DummyTrackOutput implements TrackOutput {
}
@Override
- public void sampleMetadata(long timeUs, @C.BufferFlags int flags, int size, int offset,
- CryptoData cryptoData) {
+ public void sampleMetadata(
+ long timeUs,
+ @C.BufferFlags int flags,
+ int size,
+ int offset,
+ @Nullable CryptoData cryptoData) {
// Do nothing.
}
-
}
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/TrackOutput.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/TrackOutput.java
index 6a8cef6b64..7b832eb400 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/TrackOutput.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/TrackOutput.java
@@ -125,21 +125,23 @@ public interface TrackOutput {
/**
* Called when metadata associated with a sample has been extracted from the stream.
- *
- * The corresponding sample data will have already been passed to the output via calls to
- * {@link #sampleData(ExtractorInput, int, boolean)} or
- * {@link #sampleData(ParsableByteArray, int)}.
+ *
+ *
The corresponding sample data will have already been passed to the output via calls to
+ * {@link #sampleData(ExtractorInput, int, boolean)} or {@link #sampleData(ParsableByteArray,
+ * int)}.
*
* @param timeUs The media timestamp associated with the sample, in microseconds.
* @param flags Flags associated with the sample. See {@code C.BUFFER_FLAG_*}.
* @param size The size of the sample data, in bytes.
- * @param offset The number of bytes that have been passed to
- * {@link #sampleData(ExtractorInput, int, boolean)} or
- * {@link #sampleData(ParsableByteArray, int)} since the last byte belonging to the sample
- * whose metadata is being passed.
+ * @param offset The number of bytes that have been passed to {@link #sampleData(ExtractorInput,
+ * int, boolean)} or {@link #sampleData(ParsableByteArray, int)} since the last byte belonging
+ * to the sample whose metadata is being passed.
* @param encryptionData The encryption data required to decrypt the sample. May be null.
*/
- void sampleMetadata(long timeUs, @C.BufferFlags int flags, int size, int offset,
- CryptoData encryptionData);
-
+ void sampleMetadata(
+ long timeUs,
+ @C.BufferFlags int flags,
+ int size,
+ int offset,
+ @Nullable CryptoData encryptionData);
}
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/SampleQueue.java b/library/core/src/main/java/com/google/android/exoplayer2/source/SampleQueue.java
index d9090baf3b..c378a8f9a2 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/source/SampleQueue.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/source/SampleQueue.java
@@ -568,8 +568,12 @@ public final class SampleQueue implements TrackOutput {
}
@Override
- public void sampleMetadata(long timeUs, @C.BufferFlags int flags, int size, int offset,
- CryptoData cryptoData) {
+ public void sampleMetadata(
+ long timeUs,
+ @C.BufferFlags int flags,
+ int size,
+ int offset,
+ @Nullable CryptoData cryptoData) {
if (pendingFormatAdjustment) {
format(lastUnadjustedFormat);
}
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/Chunk.java b/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/Chunk.java
index 0453a8fa12..5c109aef8c 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/Chunk.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/Chunk.java
@@ -15,13 +15,17 @@
*/
package com.google.android.exoplayer2.source.chunk;
+import android.net.Uri;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.Loader.Loadable;
+import com.google.android.exoplayer2.upstream.StatsDataSource;
import com.google.android.exoplayer2.util.Assertions;
+import java.util.List;
+import java.util.Map;
/**
* An abstract base class for {@link Loadable} implementations that load chunks of data required
@@ -64,7 +68,7 @@ public abstract class Chunk implements Loadable {
*/
public final long endTimeUs;
- protected final DataSource dataSource;
+ protected final StatsDataSource dataSource;
/**
* @param dataSource The source from which the data should be loaded.
@@ -85,7 +89,7 @@ public abstract class Chunk implements Loadable {
@Nullable Object trackSelectionData,
long startTimeUs,
long endTimeUs) {
- this.dataSource = Assertions.checkNotNull(dataSource);
+ this.dataSource = new StatsDataSource(dataSource);
this.dataSpec = Assertions.checkNotNull(dataSpec);
this.type = type;
this.trackFormat = trackFormat;
@@ -103,8 +107,31 @@ public abstract class Chunk implements Loadable {
}
/**
- * Returns the number of bytes that have been loaded.
+ * Returns the number of bytes that have been loaded. Must only be called after the load
+ * completed, failed, or was canceled.
*/
- public abstract long bytesLoaded();
+ public final long bytesLoaded() {
+ return dataSource.getBytesRead();
+ }
+ /**
+ * Returns the {@link Uri} associated with the last {@link DataSource#open} call. If redirection
+ * occurred, this is the redirected uri. Must only be called after the load completed, failed, or
+ * was canceled.
+ *
+ * @see DataSource#getUri().
+ */
+ public final Uri getUri() {
+ return dataSource.getLastOpenedUri();
+ }
+
+ /**
+ * Returns the response headers associated with the last {@link DataSource#open} call. Must only
+ * be called after the load completed, failed, or was canceled.
+ *
+ * @see DataSource#getResponseHeaders().
+ */
+ public final Map> getResponseHeaders() {
+ return dataSource.getLastResponseHeaders();
+ }
}
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkExtractorWrapper.java b/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkExtractorWrapper.java
index f043571b69..a3abc75606 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkExtractorWrapper.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkExtractorWrapper.java
@@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.source.chunk;
+import android.support.annotation.Nullable;
import android.util.SparseArray;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
@@ -103,7 +104,7 @@ public final class ChunkExtractorWrapper implements ExtractorOutput {
* @param seekTimeUs The seek position within the new chunk, or {@link C#TIME_UNSET} to output the
* whole chunk.
*/
- public void init(TrackOutputProvider trackOutputProvider, long seekTimeUs) {
+ public void init(@Nullable TrackOutputProvider trackOutputProvider, long seekTimeUs) {
this.trackOutputProvider = trackOutputProvider;
if (!extractorInitialized) {
extractor.init(this);
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ContainerMediaChunk.java b/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ContainerMediaChunk.java
index 1159f336a7..2d5ba3d2e0 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ContainerMediaChunk.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ContainerMediaChunk.java
@@ -20,6 +20,7 @@ import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.extractor.DefaultExtractorInput;
import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.extractor.ExtractorInput;
+import com.google.android.exoplayer2.extractor.PositionHolder;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.util.Assertions;
@@ -31,13 +32,15 @@ import java.io.IOException;
*/
public class ContainerMediaChunk extends BaseMediaChunk {
+ private static final PositionHolder DUMMY_POSITION_HOLDER = new PositionHolder();
+
private final int chunkCount;
private final long sampleOffsetUs;
private final ChunkExtractorWrapper extractorWrapper;
- private volatile int bytesLoaded;
+ private long nextLoadPosition;
private volatile boolean loadCanceled;
- private volatile boolean loadCompleted;
+ private boolean loadCompleted;
/**
* @param dataSource The source from which the data should be loaded.
@@ -94,11 +97,6 @@ public class ContainerMediaChunk extends BaseMediaChunk {
return loadCompleted;
}
- @Override
- public final long bytesLoaded() {
- return bytesLoaded;
- }
-
// Loadable implementation.
@Override
@@ -109,12 +107,12 @@ public class ContainerMediaChunk extends BaseMediaChunk {
@SuppressWarnings("NonAtomicVolatileUpdate")
@Override
public final void load() throws IOException, InterruptedException {
- DataSpec loadDataSpec = dataSpec.subrange(bytesLoaded);
+ DataSpec loadDataSpec = dataSpec.subrange(nextLoadPosition);
try {
// Create and open the input.
ExtractorInput input = new DefaultExtractorInput(dataSource,
loadDataSpec.absoluteStreamPosition, dataSource.open(loadDataSpec));
- if (bytesLoaded == 0) {
+ if (nextLoadPosition == 0) {
// Configure the output and set it as the target for the extractor wrapper.
BaseMediaChunkOutput output = getOutput();
output.setSampleOffsetUs(sampleOffsetUs);
@@ -126,11 +124,11 @@ public class ContainerMediaChunk extends BaseMediaChunk {
Extractor extractor = extractorWrapper.extractor;
int result = Extractor.RESULT_CONTINUE;
while (result == Extractor.RESULT_CONTINUE && !loadCanceled) {
- result = extractor.read(input, null);
+ result = extractor.read(input, DUMMY_POSITION_HOLDER);
}
Assertions.checkState(result != Extractor.RESULT_SEEK);
} finally {
- bytesLoaded = (int) (input.getPosition() - dataSpec.absoluteStreamPosition);
+ nextLoadPosition = input.getPosition() - dataSpec.absoluteStreamPosition;
}
} finally {
Util.closeQuietly(dataSource);
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/DataChunk.java b/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/DataChunk.java
index 1d3bdb57da..7ea2521eb2 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/DataChunk.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/DataChunk.java
@@ -32,7 +32,6 @@ public abstract class DataChunk extends Chunk {
private static final int READ_GRANULARITY = 16 * 1024;
private byte[] data;
- private int limit;
private volatile boolean loadCanceled;
@@ -63,11 +62,6 @@ public abstract class DataChunk extends Chunk {
return data;
}
- @Override
- public long bytesLoaded() {
- return limit;
- }
-
// Loadable implementation
@Override
@@ -79,10 +73,10 @@ public abstract class DataChunk extends Chunk {
public final void load() throws IOException, InterruptedException {
try {
dataSource.open(dataSpec);
- limit = 0;
+ int limit = 0;
int bytesRead = 0;
while (bytesRead != C.RESULT_END_OF_INPUT && !loadCanceled) {
- maybeExpandData();
+ maybeExpandData(limit);
bytesRead = dataSource.read(data, limit, READ_GRANULARITY);
if (bytesRead != -1) {
limit += bytesRead;
@@ -106,7 +100,7 @@ public abstract class DataChunk extends Chunk {
*/
protected abstract void consume(byte[] data, int limit) throws IOException;
- private void maybeExpandData() {
+ private void maybeExpandData(int limit) {
if (data == null) {
data = new byte[READ_GRANULARITY];
} else if (data.length < limit + READ_GRANULARITY) {
@@ -115,5 +109,4 @@ public abstract class DataChunk extends Chunk {
data = Arrays.copyOf(data, data.length + READ_GRANULARITY);
}
}
-
}
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/InitializationChunk.java b/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/InitializationChunk.java
index 387a90297a..d5c0d6f301 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/InitializationChunk.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/InitializationChunk.java
@@ -21,6 +21,7 @@ import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.extractor.DefaultExtractorInput;
import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.extractor.ExtractorInput;
+import com.google.android.exoplayer2.extractor.PositionHolder;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.util.Assertions;
@@ -32,9 +33,11 @@ import java.io.IOException;
*/
public final class InitializationChunk extends Chunk {
+ private static final PositionHolder DUMMY_POSITION_HOLDER = new PositionHolder();
+
private final ChunkExtractorWrapper extractorWrapper;
- private volatile int bytesLoaded;
+ private long nextLoadPosition;
private volatile boolean loadCanceled;
/**
@@ -57,11 +60,6 @@ public final class InitializationChunk extends Chunk {
this.extractorWrapper = extractorWrapper;
}
- @Override
- public long bytesLoaded() {
- return bytesLoaded;
- }
-
// Loadable implementation.
@Override
@@ -72,12 +70,12 @@ public final class InitializationChunk extends Chunk {
@SuppressWarnings("NonAtomicVolatileUpdate")
@Override
public void load() throws IOException, InterruptedException {
- DataSpec loadDataSpec = dataSpec.subrange(bytesLoaded);
+ DataSpec loadDataSpec = dataSpec.subrange(nextLoadPosition);
try {
// Create and open the input.
ExtractorInput input = new DefaultExtractorInput(dataSource,
loadDataSpec.absoluteStreamPosition, dataSource.open(loadDataSpec));
- if (bytesLoaded == 0) {
+ if (nextLoadPosition == 0) {
extractorWrapper.init(/* trackOutputProvider= */ null, C.TIME_UNSET);
}
// Load and decode the initialization data.
@@ -85,11 +83,11 @@ public final class InitializationChunk extends Chunk {
Extractor extractor = extractorWrapper.extractor;
int result = Extractor.RESULT_CONTINUE;
while (result == Extractor.RESULT_CONTINUE && !loadCanceled) {
- result = extractor.read(input, null);
+ result = extractor.read(input, DUMMY_POSITION_HOLDER);
}
Assertions.checkState(result != Extractor.RESULT_SEEK);
} finally {
- bytesLoaded = (int) (input.getPosition() - dataSpec.absoluteStreamPosition);
+ nextLoadPosition = input.getPosition() - dataSpec.absoluteStreamPosition;
}
} finally {
Util.closeQuietly(dataSource);
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/SingleSampleMediaChunk.java b/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/SingleSampleMediaChunk.java
index 17154ebc62..2c00c7690d 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/SingleSampleMediaChunk.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/SingleSampleMediaChunk.java
@@ -33,8 +33,8 @@ public final class SingleSampleMediaChunk extends BaseMediaChunk {
private final int trackType;
private final Format sampleFormat;
- private volatile int bytesLoaded;
- private volatile boolean loadCompleted;
+ private long nextLoadPosition;
+ private boolean loadCompleted;
/**
* @param dataSource The source from which the data should be loaded.
@@ -80,11 +80,6 @@ public final class SingleSampleMediaChunk extends BaseMediaChunk {
return loadCompleted;
}
- @Override
- public long bytesLoaded() {
- return bytesLoaded;
- }
-
// Loadable implementation.
@Override
@@ -95,14 +90,15 @@ public final class SingleSampleMediaChunk extends BaseMediaChunk {
@SuppressWarnings("NonAtomicVolatileUpdate")
@Override
public void load() throws IOException, InterruptedException {
- DataSpec loadDataSpec = dataSpec.subrange(bytesLoaded);
+ DataSpec loadDataSpec = dataSpec.subrange(nextLoadPosition);
try {
// Create and open the input.
long length = dataSource.open(loadDataSpec);
if (length != C.LENGTH_UNSET) {
- length += bytesLoaded;
+ length += nextLoadPosition;
}
- ExtractorInput extractorInput = new DefaultExtractorInput(dataSource, bytesLoaded, length);
+ ExtractorInput extractorInput =
+ new DefaultExtractorInput(dataSource, nextLoadPosition, length);
BaseMediaChunkOutput output = getOutput();
output.setSampleOffsetUs(0);
TrackOutput trackOutput = output.track(0, trackType);
@@ -110,10 +106,10 @@ public final class SingleSampleMediaChunk extends BaseMediaChunk {
// Load the sample data.
int result = 0;
while (result != C.RESULT_END_OF_INPUT) {
- bytesLoaded += result;
+ nextLoadPosition += result;
result = trackOutput.sampleData(extractorInput, Integer.MAX_VALUE, true);
}
- int sampleSize = bytesLoaded;
+ int sampleSize = (int) nextLoadPosition;
trackOutput.sampleMetadata(startTimeUs, C.BUFFER_FLAG_KEY_FRAME, sampleSize, 0, null);
} finally {
Util.closeQuietly(dataSource);
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/StatsDataSource.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/StatsDataSource.java
new file mode 100644
index 0000000000..71458b24a4
--- /dev/null
+++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/StatsDataSource.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2018 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.upstream;
+
+import android.net.Uri;
+import android.support.annotation.Nullable;
+import com.google.android.exoplayer2.C;
+import com.google.android.exoplayer2.util.Assertions;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * {@link DataSource} wrapper which keeps track of bytes transferred, redirected uris, and response
+ * headers.
+ */
+public final class StatsDataSource implements DataSource {
+
+ private final DataSource dataSource;
+
+ private long bytesRead;
+ private Uri lastOpenedUri;
+ private Map> lastResponseHeaders;
+
+ /**
+ * Creates the stats data source.
+ *
+ * @param dataSource The wrapped {@link DataSource}.
+ */
+ public StatsDataSource(DataSource dataSource) {
+ this.dataSource = Assertions.checkNotNull(dataSource);
+ lastOpenedUri = Uri.EMPTY;
+ lastResponseHeaders = Collections.emptyMap();
+ }
+
+ /** Returns the total number of bytes that have been read from the data source. */
+ public long getBytesRead() {
+ return bytesRead;
+ }
+
+ /**
+ * Returns the {@link Uri} associated with the last {@link #open(DataSpec)} call. If redirection
+ * occurred, this is the redirected uri.
+ */
+ public Uri getLastOpenedUri() {
+ return lastOpenedUri;
+ }
+
+ /** Returns the response headers associated with the last {@link #open(DataSpec)} call. */
+ public Map> getLastResponseHeaders() {
+ return lastResponseHeaders;
+ }
+
+ @Override
+ public long open(DataSpec dataSpec) throws IOException {
+ // Reassign defaults in case dataSource.open throws an exception.
+ lastOpenedUri = dataSpec.uri;
+ lastResponseHeaders = Collections.emptyMap();
+ long availableBytes = dataSource.open(dataSpec);
+ lastOpenedUri = Assertions.checkNotNull(getUri());
+ lastResponseHeaders = getResponseHeaders();
+ return availableBytes;
+ }
+
+ @Override
+ public int read(byte[] buffer, int offset, int readLength) throws IOException {
+ int bytesRead = dataSource.read(buffer, offset, readLength);
+ if (bytesRead != C.RESULT_END_OF_INPUT) {
+ this.bytesRead += bytesRead;
+ }
+ return bytesRead;
+ }
+
+ @Override
+ public @Nullable Uri getUri() {
+ return dataSource.getUri();
+ }
+
+ @Override
+ public Map> getResponseHeaders() {
+ return dataSource.getResponseHeaders();
+ }
+
+ @Override
+ public void close() throws IOException {
+ dataSource.close();
+ }
+}
diff --git a/library/core/src/test/java/com/google/android/exoplayer2/trackselection/AdaptiveTrackSelectionTest.java b/library/core/src/test/java/com/google/android/exoplayer2/trackselection/AdaptiveTrackSelectionTest.java
index 06c34a379d..730572bbd8 100644
--- a/library/core/src/test/java/com/google/android/exoplayer2/trackselection/AdaptiveTrackSelectionTest.java
+++ b/library/core/src/test/java/com/google/android/exoplayer2/trackselection/AdaptiveTrackSelectionTest.java
@@ -421,10 +421,5 @@ public final class AdaptiveTrackSelectionTest {
public boolean isLoadCompleted() {
return true;
}
-
- @Override
- public long bytesLoaded() {
- return 0;
- }
}
}
diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/PlayerEmsgHandler.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/PlayerEmsgHandler.java
index 0ef6b5ff1a..a4a37cd904 100644
--- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/PlayerEmsgHandler.java
+++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/PlayerEmsgHandler.java
@@ -336,7 +336,7 @@ public final class PlayerEmsgHandler implements Handler.Callback {
@Override
public void sampleMetadata(
- long timeUs, int flags, int size, int offset, CryptoData encryptionData) {
+ long timeUs, int flags, int size, int offset, @Nullable CryptoData encryptionData) {
sampleQueue.sampleMetadata(timeUs, flags, size, offset, encryptionData);
parseAndDiscardSamples();
}
diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaChunk.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaChunk.java
index 2805e35db7..8c151e59c1 100644
--- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaChunk.java
+++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaChunk.java
@@ -80,11 +80,11 @@ import java.util.concurrent.atomic.AtomicInteger;
private ParsableByteArray id3Data;
private HlsSampleStreamWrapper output;
private int initSegmentBytesLoaded;
- private int bytesLoaded;
+ private int nextLoadPosition;
private boolean id3TimestampPeeked;
private boolean initLoadCompleted;
private volatile boolean loadCanceled;
- private volatile boolean loadCompleted;
+ private boolean loadCompleted;
/**
* @param extractorFactory A {@link HlsExtractorFactory} from which the HLS media chunk extractor
@@ -145,8 +145,7 @@ import java.util.concurrent.atomic.AtomicInteger;
this.hlsUrl = hlsUrl;
this.isMasterTimestampSource = isMasterTimestampSource;
this.timestampAdjuster = timestampAdjuster;
- // Note: this.dataSource and dataSource may be different.
- this.isEncrypted = this.dataSource instanceof Aes128DataSource;
+ this.isEncrypted = fullSegmentEncryptionKey != null;
this.hasGapTag = hasGapTag;
this.extractorFactory = extractorFactory;
this.muxedCaptionFormats = muxedCaptionFormats;
@@ -181,11 +180,6 @@ import java.util.concurrent.atomic.AtomicInteger;
return loadCompleted;
}
- @Override
- public long bytesLoaded() {
- return bytesLoaded;
- }
-
// Loadable implementation
@Override
@@ -237,9 +231,9 @@ import java.util.concurrent.atomic.AtomicInteger;
boolean skipLoadedBytes;
if (isEncrypted) {
loadDataSpec = dataSpec;
- skipLoadedBytes = bytesLoaded != 0;
+ skipLoadedBytes = nextLoadPosition != 0;
} else {
- loadDataSpec = dataSpec.subrange(bytesLoaded);
+ loadDataSpec = dataSpec.subrange(nextLoadPosition);
skipLoadedBytes = false;
}
if (!isMasterTimestampSource) {
@@ -257,7 +251,7 @@ import java.util.concurrent.atomic.AtomicInteger;
? timestampAdjuster.adjustTsTimestamp(id3Timestamp) : startTimeUs);
}
if (skipLoadedBytes) {
- input.skipFully(bytesLoaded);
+ input.skipFully(nextLoadPosition);
}
try {
int result = Extractor.RESULT_CONTINUE;
@@ -265,7 +259,7 @@ import java.util.concurrent.atomic.AtomicInteger;
result = extractor.read(input, null);
}
} finally {
- bytesLoaded = (int) (input.getPosition() - dataSpec.absoluteStreamPosition);
+ nextLoadPosition = (int) (input.getPosition() - dataSpec.absoluteStreamPosition);
}
} finally {
Util.closeQuietly(dataSource);