Commit dd14500e by tonihei Committed by Oliver Woodman

Add url (after redirection) to LoadEventInfo.

This url is readily available when creating media source events (from the
data source) but so far not published to external listeners. This change
adds a new field to LoadEventInfo which corresponds to DataSource.getUri().

Issue:#2054

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=202459049
parent 236eb5ce
...@@ -50,6 +50,9 @@ ...@@ -50,6 +50,9 @@
([#4403](https://github.com/google/ExoPlayer/issues/4413)). ([#4403](https://github.com/google/ExoPlayer/issues/4413)).
* Add support for multiple audio and video tracks in MPEG-PS streams * Add support for multiple audio and video tracks in MPEG-PS streams
([#4406](https://github.com/google/ExoPlayer/issues/4406)). ([#4406](https://github.com/google/ExoPlayer/issues/4406)).
* Add uri field to `LoadEventInfo` in `MediaSourceEventListener` or
`AnalyticsListener` callbacks. This uri is the redirected uri if redirection
occurred ([#2054](https://github.com/google/ExoPlayer/issues/2054)).
### 2.8.2 ### ### 2.8.2 ###
......
...@@ -40,6 +40,7 @@ import com.google.android.exoplayer2.upstream.DataSpec; ...@@ -40,6 +40,7 @@ import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.Loader; import com.google.android.exoplayer2.upstream.Loader;
import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction; import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction;
import com.google.android.exoplayer2.upstream.Loader.Loadable; import com.google.android.exoplayer2.upstream.Loader.Loadable;
import com.google.android.exoplayer2.upstream.StatsDataSource;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.ConditionVariable; import com.google.android.exoplayer2.util.ConditionVariable;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
...@@ -491,6 +492,7 @@ import java.util.Arrays; ...@@ -491,6 +492,7 @@ import java.util.Arrays;
} }
eventDispatcher.loadCompleted( eventDispatcher.loadCompleted(
loadable.dataSpec, loadable.dataSpec,
loadable.dataSource.getLastOpenedUri(),
C.DATA_TYPE_MEDIA, C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN, C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null, /* trackFormat= */ null,
...@@ -500,7 +502,7 @@ import java.util.Arrays; ...@@ -500,7 +502,7 @@ import java.util.Arrays;
durationUs, durationUs,
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
loadable.bytesLoaded); loadable.dataSource.getBytesRead());
copyLengthFromLoader(loadable); copyLengthFromLoader(loadable);
loadingFinished = true; loadingFinished = true;
callback.onContinueLoadingRequested(this); callback.onContinueLoadingRequested(this);
...@@ -511,6 +513,7 @@ import java.util.Arrays; ...@@ -511,6 +513,7 @@ import java.util.Arrays;
long loadDurationMs, boolean released) { long loadDurationMs, boolean released) {
eventDispatcher.loadCanceled( eventDispatcher.loadCanceled(
loadable.dataSpec, loadable.dataSpec,
loadable.dataSource.getLastOpenedUri(),
C.DATA_TYPE_MEDIA, C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN, C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null, /* trackFormat= */ null,
...@@ -520,7 +523,7 @@ import java.util.Arrays; ...@@ -520,7 +523,7 @@ import java.util.Arrays;
durationUs, durationUs,
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
loadable.bytesLoaded); loadable.dataSource.getBytesRead());
if (!released) { if (!released) {
copyLengthFromLoader(loadable); copyLengthFromLoader(loadable);
for (SampleQueue sampleQueue : sampleQueues) { for (SampleQueue sampleQueue : sampleQueues) {
...@@ -539,9 +542,23 @@ import java.util.Arrays; ...@@ -539,9 +542,23 @@ import java.util.Arrays;
long loadDurationMs, long loadDurationMs,
IOException error, IOException error,
int errorCount) { int errorCount) {
boolean isErrorFatal = isLoadableExceptionFatal(error); copyLengthFromLoader(loadable);
LoadErrorAction retryAction;
if (isLoadableExceptionFatal(error)) {
retryAction = Loader.DONT_RETRY_FATAL;
} else {
int extractedSamplesCount = getExtractedSamplesCount();
boolean madeProgress = extractedSamplesCount > extractedSamplesCountAtStartOfLoad;
retryAction =
configureRetry(loadable, extractedSamplesCount)
? (madeProgress ? Loader.RETRY_RESET_ERROR_COUNT : Loader.RETRY)
: Loader.DONT_RETRY;
}
boolean wasCanceled =
retryAction == Loader.DONT_RETRY || retryAction == Loader.DONT_RETRY_FATAL;
eventDispatcher.loadError( eventDispatcher.loadError(
loadable.dataSpec, loadable.dataSpec,
loadable.dataSource.getLastOpenedUri(),
C.DATA_TYPE_MEDIA, C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN, C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null, /* trackFormat= */ null,
...@@ -551,18 +568,10 @@ import java.util.Arrays; ...@@ -551,18 +568,10 @@ import java.util.Arrays;
durationUs, durationUs,
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
loadable.bytesLoaded, loadable.dataSource.getBytesRead(),
error, error,
/* wasCanceled= */ isErrorFatal); wasCanceled);
copyLengthFromLoader(loadable); return retryAction;
if (isErrorFatal) {
return Loader.DONT_RETRY_FATAL;
}
int extractedSamplesCount = getExtractedSamplesCount();
boolean madeProgress = extractedSamplesCount > extractedSamplesCountAtStartOfLoad;
return configureRetry(loadable, extractedSamplesCount)
? (madeProgress ? Loader.RETRY_RESET_ERROR_COUNT : Loader.RETRY)
: Loader.DONT_RETRY;
} }
// ExtractorOutput implementation. Called by the loading thread. // ExtractorOutput implementation. Called by the loading thread.
...@@ -663,6 +672,7 @@ import java.util.Arrays; ...@@ -663,6 +672,7 @@ import java.util.Arrays;
long elapsedRealtimeMs = loader.startLoading(loadable, this, actualMinLoadableRetryCount); long elapsedRealtimeMs = loader.startLoading(loadable, this, actualMinLoadableRetryCount);
eventDispatcher.loadStarted( eventDispatcher.loadStarted(
loadable.dataSpec, loadable.dataSpec,
loadable.dataSpec.uri,
C.DATA_TYPE_MEDIA, C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN, C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null, /* trackFormat= */ null,
...@@ -803,7 +813,7 @@ import java.util.Arrays; ...@@ -803,7 +813,7 @@ import java.util.Arrays;
/* package */ final class ExtractingLoadable implements Loadable { /* package */ final class ExtractingLoadable implements Loadable {
private final Uri uri; private final Uri uri;
private final DataSource dataSource; private final StatsDataSource dataSource;
private final ExtractorHolder extractorHolder; private final ExtractorHolder extractorHolder;
private final ConditionVariable loadCondition; private final ConditionVariable loadCondition;
private final PositionHolder positionHolder; private final PositionHolder positionHolder;
...@@ -814,17 +824,17 @@ import java.util.Arrays; ...@@ -814,17 +824,17 @@ import java.util.Arrays;
private long seekTimeUs; private long seekTimeUs;
private DataSpec dataSpec; private DataSpec dataSpec;
private long length; private long length;
private long bytesLoaded;
public ExtractingLoadable(Uri uri, DataSource dataSource, ExtractorHolder extractorHolder, public ExtractingLoadable(Uri uri, DataSource dataSource, ExtractorHolder extractorHolder,
ConditionVariable loadCondition) { ConditionVariable loadCondition) {
this.uri = Assertions.checkNotNull(uri); this.uri = Assertions.checkNotNull(uri);
this.dataSource = Assertions.checkNotNull(dataSource); this.dataSource = new StatsDataSource(dataSource);
this.extractorHolder = Assertions.checkNotNull(extractorHolder); this.extractorHolder = Assertions.checkNotNull(extractorHolder);
this.loadCondition = loadCondition; this.loadCondition = loadCondition;
this.positionHolder = new PositionHolder(); this.positionHolder = new PositionHolder();
this.pendingExtractorSeek = true; this.pendingExtractorSeek = true;
this.length = C.LENGTH_UNSET; this.length = C.LENGTH_UNSET;
dataSpec = new DataSpec(uri, positionHolder.position, C.LENGTH_UNSET, customCacheKey);
} }
public void setLoadPosition(long position, long timeUs) { public void setLoadPosition(long position, long timeUs) {
...@@ -870,7 +880,6 @@ import java.util.Arrays; ...@@ -870,7 +880,6 @@ import java.util.Arrays;
result = Extractor.RESULT_CONTINUE; result = Extractor.RESULT_CONTINUE;
} else if (input != null) { } else if (input != null) {
positionHolder.position = input.getPosition(); positionHolder.position = input.getPosition();
bytesLoaded = positionHolder.position - dataSpec.absoluteStreamPosition;
} }
Util.closeQuietly(dataSource); Util.closeQuietly(dataSource);
} }
......
...@@ -27,6 +27,7 @@ import com.google.android.exoplayer2.upstream.DataSpec; ...@@ -27,6 +27,7 @@ import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.Loader; import com.google.android.exoplayer2.upstream.Loader;
import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction; import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction;
import com.google.android.exoplayer2.upstream.Loader.Loadable; import com.google.android.exoplayer2.upstream.Loader.Loadable;
import com.google.android.exoplayer2.upstream.StatsDataSource;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import java.io.IOException; import java.io.IOException;
...@@ -144,6 +145,7 @@ import java.util.Arrays; ...@@ -144,6 +145,7 @@ import java.util.Arrays;
minLoadableRetryCount); minLoadableRetryCount);
eventDispatcher.loadStarted( eventDispatcher.loadStarted(
dataSpec, dataSpec,
dataSpec.uri,
C.DATA_TYPE_MEDIA, C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN, C.TRACK_TYPE_UNKNOWN,
format, format,
...@@ -192,8 +194,13 @@ import java.util.Arrays; ...@@ -192,8 +194,13 @@ import java.util.Arrays;
@Override @Override
public void onLoadCompleted(SourceLoadable loadable, long elapsedRealtimeMs, public void onLoadCompleted(SourceLoadable loadable, long elapsedRealtimeMs,
long loadDurationMs) { long loadDurationMs) {
sampleSize = (int) loadable.dataSource.getBytesRead();
sampleData = loadable.sampleData;
loadingFinished = true;
loadingSucceeded = true;
eventDispatcher.loadCompleted( eventDispatcher.loadCompleted(
loadable.dataSpec, loadable.dataSpec,
loadable.dataSource.getLastOpenedUri(),
C.DATA_TYPE_MEDIA, C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN, C.TRACK_TYPE_UNKNOWN,
format, format,
...@@ -203,11 +210,7 @@ import java.util.Arrays; ...@@ -203,11 +210,7 @@ import java.util.Arrays;
durationUs, durationUs,
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
loadable.sampleSize); sampleSize);
sampleSize = loadable.sampleSize;
sampleData = loadable.sampleData;
loadingFinished = true;
loadingSucceeded = true;
} }
@Override @Override
...@@ -215,6 +218,7 @@ import java.util.Arrays; ...@@ -215,6 +218,7 @@ import java.util.Arrays;
boolean released) { boolean released) {
eventDispatcher.loadCanceled( eventDispatcher.loadCanceled(
loadable.dataSpec, loadable.dataSpec,
loadable.dataSource.getLastOpenedUri(),
C.DATA_TYPE_MEDIA, C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN, C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null, /* trackFormat= */ null,
...@@ -224,7 +228,7 @@ import java.util.Arrays; ...@@ -224,7 +228,7 @@ import java.util.Arrays;
durationUs, durationUs,
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
loadable.sampleSize); loadable.dataSource.getBytesRead());
} }
@Override @Override
...@@ -237,6 +241,7 @@ import java.util.Arrays; ...@@ -237,6 +241,7 @@ import java.util.Arrays;
boolean cancel = treatLoadErrorsAsEndOfStream && errorCount >= minLoadableRetryCount; boolean cancel = treatLoadErrorsAsEndOfStream && errorCount >= minLoadableRetryCount;
eventDispatcher.loadError( eventDispatcher.loadError(
loadable.dataSpec, loadable.dataSpec,
loadable.dataSource.getLastOpenedUri(),
C.DATA_TYPE_MEDIA, C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN, C.TRACK_TYPE_UNKNOWN,
format, format,
...@@ -246,7 +251,7 @@ import java.util.Arrays; ...@@ -246,7 +251,7 @@ import java.util.Arrays;
durationUs, durationUs,
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
loadable.sampleSize, loadable.dataSource.getBytesRead(),
error, error,
/* wasCanceled= */ cancel); /* wasCanceled= */ cancel);
if (cancel) { if (cancel) {
...@@ -336,14 +341,13 @@ import java.util.Arrays; ...@@ -336,14 +341,13 @@ import java.util.Arrays;
public final DataSpec dataSpec; public final DataSpec dataSpec;
private final DataSource dataSource; private final StatsDataSource dataSource;
private int sampleSize;
private byte[] sampleData; private byte[] sampleData;
public SourceLoadable(DataSpec dataSpec, DataSource dataSource) { public SourceLoadable(DataSpec dataSpec, DataSource dataSource) {
this.dataSpec = dataSpec; this.dataSpec = dataSpec;
this.dataSource = dataSource; this.dataSource = new StatsDataSource(dataSource);
} }
@Override @Override
...@@ -353,15 +357,15 @@ import java.util.Arrays; ...@@ -353,15 +357,15 @@ import java.util.Arrays;
@Override @Override
public void load() throws IOException, InterruptedException { public void load() throws IOException, InterruptedException {
// We always load from the beginning, so reset the sampleSize to 0. // We always load from the beginning, so reset bytesRead to 0.
sampleSize = 0; dataSource.resetBytesRead();
try { try {
// Create and open the input. // Create and open the input.
dataSource.open(dataSpec); dataSource.open(dataSpec);
// Load the sample data. // Load the sample data.
int result = 0; int result = 0;
while (result != C.RESULT_END_OF_INPUT) { while (result != C.RESULT_END_OF_INPUT) {
sampleSize += result; int sampleSize = (int) dataSource.getBytesRead();
if (sampleData == null) { if (sampleData == null) {
sampleData = new byte[INITIAL_SAMPLE_SIZE]; sampleData = new byte[INITIAL_SAMPLE_SIZE];
} else if (sampleSize == sampleData.length) { } else if (sampleSize == sampleData.length) {
......
...@@ -539,6 +539,7 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> { ...@@ -539,6 +539,7 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
createEventDispatcher(/* mediaPeriodId= */ null) createEventDispatcher(/* mediaPeriodId= */ null)
.loadError( .loadError(
dataSpec, dataSpec,
dataSpec.uri,
C.DATA_TYPE_AD, C.DATA_TYPE_AD,
C.TRACK_TYPE_UNKNOWN, C.TRACK_TYPE_UNKNOWN,
/* loadDurationMs= */ 0, /* loadDurationMs= */ 0,
...@@ -580,6 +581,7 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> { ...@@ -580,6 +581,7 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
createEventDispatcher(mediaPeriodId) createEventDispatcher(mediaPeriodId)
.loadError( .loadError(
new DataSpec(adUri), new DataSpec(adUri),
adUri,
C.DATA_TYPE_AD, C.DATA_TYPE_AD,
C.TRACK_TYPE_UNKNOWN, C.TRACK_TYPE_UNKNOWN,
/* loadDurationMs= */ 0, /* loadDurationMs= */ 0,
......
...@@ -386,9 +386,18 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S ...@@ -386,9 +386,18 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
@Override @Override
public void onLoadCompleted(Chunk loadable, long elapsedRealtimeMs, long loadDurationMs) { public void onLoadCompleted(Chunk loadable, long elapsedRealtimeMs, long loadDurationMs) {
chunkSource.onChunkLoadCompleted(loadable); chunkSource.onChunkLoadCompleted(loadable);
eventDispatcher.loadCompleted(loadable.dataSpec, loadable.type, primaryTrackType, eventDispatcher.loadCompleted(
loadable.trackFormat, loadable.trackSelectionReason, loadable.trackSelectionData, loadable.dataSpec,
loadable.startTimeUs, loadable.endTimeUs, elapsedRealtimeMs, loadDurationMs, loadable.getUri(),
loadable.type,
primaryTrackType,
loadable.trackFormat,
loadable.trackSelectionReason,
loadable.trackSelectionData,
loadable.startTimeUs,
loadable.endTimeUs,
elapsedRealtimeMs,
loadDurationMs,
loadable.bytesLoaded()); loadable.bytesLoaded());
callback.onContinueLoadingRequested(this); callback.onContinueLoadingRequested(this);
} }
...@@ -396,9 +405,18 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S ...@@ -396,9 +405,18 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
@Override @Override
public void onLoadCanceled(Chunk loadable, long elapsedRealtimeMs, long loadDurationMs, public void onLoadCanceled(Chunk loadable, long elapsedRealtimeMs, long loadDurationMs,
boolean released) { boolean released) {
eventDispatcher.loadCanceled(loadable.dataSpec, loadable.type, primaryTrackType, eventDispatcher.loadCanceled(
loadable.trackFormat, loadable.trackSelectionReason, loadable.trackSelectionData, loadable.dataSpec,
loadable.startTimeUs, loadable.endTimeUs, elapsedRealtimeMs, loadDurationMs, loadable.getUri(),
loadable.type,
primaryTrackType,
loadable.trackFormat,
loadable.trackSelectionReason,
loadable.trackSelectionData,
loadable.startTimeUs,
loadable.endTimeUs,
elapsedRealtimeMs,
loadDurationMs,
loadable.bytesLoaded()); loadable.bytesLoaded());
if (!released) { if (!released) {
primarySampleQueue.reset(); primarySampleQueue.reset();
...@@ -436,10 +454,21 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S ...@@ -436,10 +454,21 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
} }
} }
} }
eventDispatcher.loadError(loadable.dataSpec, loadable.type, primaryTrackType, eventDispatcher.loadError(
loadable.trackFormat, loadable.trackSelectionReason, loadable.trackSelectionData, loadable.dataSpec,
loadable.startTimeUs, loadable.endTimeUs, elapsedRealtimeMs, loadDurationMs, bytesLoaded, loadable.getUri(),
error, canceled); loadable.type,
primaryTrackType,
loadable.trackFormat,
loadable.trackSelectionReason,
loadable.trackSelectionData,
loadable.startTimeUs,
loadable.endTimeUs,
elapsedRealtimeMs,
loadDurationMs,
bytesLoaded,
error,
canceled);
if (canceled) { if (canceled) {
callback.onContinueLoadingRequested(this); callback.onContinueLoadingRequested(this);
return Loader.DONT_RETRY; return Loader.DONT_RETRY;
...@@ -493,9 +522,17 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S ...@@ -493,9 +522,17 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
mediaChunks.add(mediaChunk); mediaChunks.add(mediaChunk);
} }
long elapsedRealtimeMs = loader.startLoading(loadable, this, minLoadableRetryCount); long elapsedRealtimeMs = loader.startLoading(loadable, this, minLoadableRetryCount);
eventDispatcher.loadStarted(loadable.dataSpec, loadable.type, primaryTrackType, eventDispatcher.loadStarted(
loadable.trackFormat, loadable.trackSelectionReason, loadable.trackSelectionData, loadable.dataSpec,
loadable.startTimeUs, loadable.endTimeUs, elapsedRealtimeMs); loadable.dataSpec.uri,
loadable.type,
primaryTrackType,
loadable.trackFormat,
loadable.trackSelectionReason,
loadable.trackSelectionData,
loadable.startTimeUs,
loadable.endTimeUs,
elapsedRealtimeMs);
return true; return true;
} }
......
...@@ -77,11 +77,10 @@ public final class ParsingLoadable<T> implements Loadable { ...@@ -77,11 +77,10 @@ public final class ParsingLoadable<T> implements Loadable {
*/ */
public final int type; public final int type;
private final DataSource dataSource; private final StatsDataSource dataSource;
private final Parser<? extends T> parser; private final Parser<? extends T> parser;
private volatile @Nullable T result; private volatile @Nullable T result;
private volatile long bytesLoaded;
/** /**
* @param dataSource A {@link DataSource} to use when loading the data. * @param dataSource A {@link DataSource} to use when loading the data.
...@@ -105,7 +104,7 @@ public final class ParsingLoadable<T> implements Loadable { ...@@ -105,7 +104,7 @@ public final class ParsingLoadable<T> implements Loadable {
*/ */
public ParsingLoadable(DataSource dataSource, DataSpec dataSpec, int type, public ParsingLoadable(DataSource dataSource, DataSpec dataSpec, int type,
Parser<? extends T> parser) { Parser<? extends T> parser) {
this.dataSource = dataSource; this.dataSource = new StatsDataSource(dataSource);
this.dataSpec = dataSpec; this.dataSpec = dataSpec;
this.type = type; this.type = type;
this.parser = parser; this.parser = parser;
...@@ -118,12 +117,19 @@ public final class ParsingLoadable<T> implements Loadable { ...@@ -118,12 +117,19 @@ public final class ParsingLoadable<T> implements Loadable {
/** /**
* Returns the number of bytes loaded. In the case that the network response was compressed, the * Returns the number of bytes loaded. In the case that the network response was compressed, the
* value returned is the size of the data <em>after</em> decompression. * value returned is the size of the data <em>after</em> decompression. Must only be called after
* * the load completed, failed, or was canceled.
* @return The number of bytes loaded.
*/ */
public long bytesLoaded() { public long bytesLoaded() {
return bytesLoaded; return dataSource.getBytesRead();
}
/**
* Returns the {@link Uri} from which data was read. If redirection occurred, this is the
* redirected uri. Must only be called after the load completed, failed, or was canceled.
*/
public Uri getUri() {
return dataSource.getLastOpenedUri();
} }
@Override @Override
...@@ -133,13 +139,14 @@ public final class ParsingLoadable<T> implements Loadable { ...@@ -133,13 +139,14 @@ public final class ParsingLoadable<T> implements Loadable {
@Override @Override
public final void load() throws IOException { public final void load() throws IOException {
// We always load from the beginning, so reset bytesRead to 0.
dataSource.resetBytesRead();
DataSourceInputStream inputStream = new DataSourceInputStream(dataSource, dataSpec); DataSourceInputStream inputStream = new DataSourceInputStream(dataSource, dataSpec);
try { try {
inputStream.open(); inputStream.open();
Uri dataSourceUri = Assertions.checkNotNull(dataSource.getUri()); Uri dataSourceUri = Assertions.checkNotNull(dataSource.getUri());
result = parser.parse(dataSourceUri, inputStream); result = parser.parse(dataSourceUri, inputStream);
} finally { } finally {
bytesLoaded = inputStream.bytesRead();
Util.closeQuietly(inputStream); Util.closeQuietly(inputStream);
} }
} }
......
...@@ -47,6 +47,11 @@ public final class StatsDataSource implements DataSource { ...@@ -47,6 +47,11 @@ public final class StatsDataSource implements DataSource {
lastResponseHeaders = Collections.emptyMap(); lastResponseHeaders = Collections.emptyMap();
} }
/** Resets the number of bytes read as returned from {@link #getBytesRead()} to zero. */
public void resetBytesRead() {
bytesRead = 0;
}
/** Returns the total number of bytes that have been read from the data source. */ /** Returns the total number of bytes that have been read from the data source. */
public long getBytesRead() { public long getBytesRead() {
return bytesRead; return bytesRead;
......
...@@ -638,6 +638,7 @@ public final class DashMediaSource extends BaseMediaSource { ...@@ -638,6 +638,7 @@ public final class DashMediaSource extends BaseMediaSource {
long elapsedRealtimeMs, long loadDurationMs) { long elapsedRealtimeMs, long loadDurationMs) {
manifestEventDispatcher.loadCompleted( manifestEventDispatcher.loadCompleted(
loadable.dataSpec, loadable.dataSpec,
loadable.getUri(),
loadable.type, loadable.type,
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
...@@ -699,7 +700,9 @@ public final class DashMediaSource extends BaseMediaSource { ...@@ -699,7 +700,9 @@ public final class DashMediaSource extends BaseMediaSource {
synchronized (manifestUriLock) { synchronized (manifestUriLock) {
// This condition checks that replaceManifestUri wasn't called between the start and end of // This condition checks that replaceManifestUri wasn't called between the start and end of
// this load. If it was, we ignore the manifest location and prefer the manual replacement. // this load. If it was, we ignore the manifest location and prefer the manual replacement.
if (loadable.dataSpec.uri == manifestUri) { @SuppressWarnings("ReferenceEquality")
boolean isSameUriInstance = loadable.dataSpec.uri == manifestUri;
if (isSameUriInstance) {
manifestUri = manifest.location; manifestUri = manifest.location;
} }
} }
...@@ -725,6 +728,7 @@ public final class DashMediaSource extends BaseMediaSource { ...@@ -725,6 +728,7 @@ public final class DashMediaSource extends BaseMediaSource {
boolean isFatal = error instanceof ParserException; boolean isFatal = error instanceof ParserException;
manifestEventDispatcher.loadError( manifestEventDispatcher.loadError(
loadable.dataSpec, loadable.dataSpec,
loadable.getUri(),
loadable.type, loadable.type,
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
...@@ -738,6 +742,7 @@ public final class DashMediaSource extends BaseMediaSource { ...@@ -738,6 +742,7 @@ public final class DashMediaSource extends BaseMediaSource {
long elapsedRealtimeMs, long loadDurationMs) { long elapsedRealtimeMs, long loadDurationMs) {
manifestEventDispatcher.loadCompleted( manifestEventDispatcher.loadCompleted(
loadable.dataSpec, loadable.dataSpec,
loadable.getUri(),
loadable.type, loadable.type,
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
...@@ -752,6 +757,7 @@ public final class DashMediaSource extends BaseMediaSource { ...@@ -752,6 +757,7 @@ public final class DashMediaSource extends BaseMediaSource {
IOException error) { IOException error) {
manifestEventDispatcher.loadError( manifestEventDispatcher.loadError(
loadable.dataSpec, loadable.dataSpec,
loadable.getUri(),
loadable.type, loadable.type,
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
...@@ -766,6 +772,7 @@ public final class DashMediaSource extends BaseMediaSource { ...@@ -766,6 +772,7 @@ public final class DashMediaSource extends BaseMediaSource {
long loadDurationMs) { long loadDurationMs) {
manifestEventDispatcher.loadCanceled( manifestEventDispatcher.loadCanceled(
loadable.dataSpec, loadable.dataSpec,
loadable.getUri(),
loadable.type, loadable.type,
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
...@@ -953,7 +960,8 @@ public final class DashMediaSource extends BaseMediaSource { ...@@ -953,7 +960,8 @@ public final class DashMediaSource extends BaseMediaSource {
private <T> void startLoading(ParsingLoadable<T> loadable, private <T> void startLoading(ParsingLoadable<T> loadable,
Loader.Callback<ParsingLoadable<T>> callback, int minRetryCount) { Loader.Callback<ParsingLoadable<T>> callback, int minRetryCount) {
long elapsedRealtimeMs = loader.startLoading(loadable, callback, minRetryCount); long elapsedRealtimeMs = loader.startLoading(loadable, callback, minRetryCount);
manifestEventDispatcher.loadStarted(loadable.dataSpec, loadable.type, elapsedRealtimeMs); manifestEventDispatcher.loadStarted(
loadable.dataSpec, loadable.dataSpec.uri, loadable.type, elapsedRealtimeMs);
} }
private long getNowUnixTimeUs() { private long getNowUnixTimeUs() {
......
...@@ -562,9 +562,17 @@ import java.util.Arrays; ...@@ -562,9 +562,17 @@ import java.util.Arrays;
mediaChunks.add(mediaChunk); mediaChunks.add(mediaChunk);
} }
long elapsedRealtimeMs = loader.startLoading(loadable, this, minLoadableRetryCount); long elapsedRealtimeMs = loader.startLoading(loadable, this, minLoadableRetryCount);
eventDispatcher.loadStarted(loadable.dataSpec, loadable.type, trackType, loadable.trackFormat, eventDispatcher.loadStarted(
loadable.trackSelectionReason, loadable.trackSelectionData, loadable.startTimeUs, loadable.dataSpec,
loadable.endTimeUs, elapsedRealtimeMs); loadable.dataSpec.uri,
loadable.type,
trackType,
loadable.trackFormat,
loadable.trackSelectionReason,
loadable.trackSelectionData,
loadable.startTimeUs,
loadable.endTimeUs,
elapsedRealtimeMs);
return true; return true;
} }
...@@ -578,9 +586,19 @@ import java.util.Arrays; ...@@ -578,9 +586,19 @@ import java.util.Arrays;
@Override @Override
public void onLoadCompleted(Chunk loadable, long elapsedRealtimeMs, long loadDurationMs) { public void onLoadCompleted(Chunk loadable, long elapsedRealtimeMs, long loadDurationMs) {
chunkSource.onChunkLoadCompleted(loadable); chunkSource.onChunkLoadCompleted(loadable);
eventDispatcher.loadCompleted(loadable.dataSpec, loadable.type, trackType, loadable.trackFormat, eventDispatcher.loadCompleted(
loadable.trackSelectionReason, loadable.trackSelectionData, loadable.startTimeUs, loadable.dataSpec,
loadable.endTimeUs, elapsedRealtimeMs, loadDurationMs, loadable.bytesLoaded()); loadable.getUri(),
loadable.type,
trackType,
loadable.trackFormat,
loadable.trackSelectionReason,
loadable.trackSelectionData,
loadable.startTimeUs,
loadable.endTimeUs,
elapsedRealtimeMs,
loadDurationMs,
loadable.bytesLoaded());
if (!prepared) { if (!prepared) {
continueLoading(lastSeekPositionUs); continueLoading(lastSeekPositionUs);
} else { } else {
...@@ -591,9 +609,19 @@ import java.util.Arrays; ...@@ -591,9 +609,19 @@ import java.util.Arrays;
@Override @Override
public void onLoadCanceled(Chunk loadable, long elapsedRealtimeMs, long loadDurationMs, public void onLoadCanceled(Chunk loadable, long elapsedRealtimeMs, long loadDurationMs,
boolean released) { boolean released) {
eventDispatcher.loadCanceled(loadable.dataSpec, loadable.type, trackType, loadable.trackFormat, eventDispatcher.loadCanceled(
loadable.trackSelectionReason, loadable.trackSelectionData, loadable.startTimeUs, loadable.dataSpec,
loadable.endTimeUs, elapsedRealtimeMs, loadDurationMs, loadable.bytesLoaded()); loadable.getUri(),
loadable.type,
trackType,
loadable.trackFormat,
loadable.trackSelectionReason,
loadable.trackSelectionData,
loadable.startTimeUs,
loadable.endTimeUs,
elapsedRealtimeMs,
loadDurationMs,
loadable.bytesLoaded());
if (!released) { if (!released) {
resetSampleQueues(); resetSampleQueues();
if (enabledTrackGroupCount > 0) { if (enabledTrackGroupCount > 0) {
...@@ -623,9 +651,20 @@ import java.util.Arrays; ...@@ -623,9 +651,20 @@ import java.util.Arrays;
} }
canceled = true; canceled = true;
} }
eventDispatcher.loadError(loadable.dataSpec, loadable.type, trackType, loadable.trackFormat, eventDispatcher.loadError(
loadable.trackSelectionReason, loadable.trackSelectionData, loadable.startTimeUs, loadable.dataSpec,
loadable.endTimeUs, elapsedRealtimeMs, loadDurationMs, loadable.bytesLoaded(), error, loadable.getUri(),
loadable.type,
trackType,
loadable.trackFormat,
loadable.trackSelectionReason,
loadable.trackSelectionData,
loadable.startTimeUs,
loadable.endTimeUs,
elapsedRealtimeMs,
loadDurationMs,
loadable.bytesLoaded(),
error,
canceled); canceled);
if (canceled) { if (canceled) {
if (!prepared) { if (!prepared) {
......
...@@ -102,7 +102,10 @@ public final class DefaultHlsPlaylistTracker ...@@ -102,7 +102,10 @@ public final class DefaultHlsPlaylistTracker
long elapsedRealtime = long elapsedRealtime =
initialPlaylistLoader.startLoading(masterPlaylistLoadable, this, minRetryCount); initialPlaylistLoader.startLoading(masterPlaylistLoadable, this, minRetryCount);
eventDispatcher.loadStarted( eventDispatcher.loadStarted(
masterPlaylistLoadable.dataSpec, masterPlaylistLoadable.type, elapsedRealtime); masterPlaylistLoadable.dataSpec,
masterPlaylistLoadable.dataSpec.uri,
masterPlaylistLoadable.type,
elapsedRealtime);
} }
@Override @Override
...@@ -209,6 +212,7 @@ public final class DefaultHlsPlaylistTracker ...@@ -209,6 +212,7 @@ public final class DefaultHlsPlaylistTracker
} }
eventDispatcher.loadCompleted( eventDispatcher.loadCompleted(
loadable.dataSpec, loadable.dataSpec,
loadable.getUri(),
C.DATA_TYPE_MANIFEST, C.DATA_TYPE_MANIFEST,
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
...@@ -223,6 +227,7 @@ public final class DefaultHlsPlaylistTracker ...@@ -223,6 +227,7 @@ public final class DefaultHlsPlaylistTracker
boolean released) { boolean released) {
eventDispatcher.loadCanceled( eventDispatcher.loadCanceled(
loadable.dataSpec, loadable.dataSpec,
loadable.getUri(),
C.DATA_TYPE_MANIFEST, C.DATA_TYPE_MANIFEST,
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
...@@ -239,6 +244,7 @@ public final class DefaultHlsPlaylistTracker ...@@ -239,6 +244,7 @@ public final class DefaultHlsPlaylistTracker
boolean isFatal = error instanceof ParserException; boolean isFatal = error instanceof ParserException;
eventDispatcher.loadError( eventDispatcher.loadError(
loadable.dataSpec, loadable.dataSpec,
loadable.getUri(),
C.DATA_TYPE_MANIFEST, C.DATA_TYPE_MANIFEST,
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
...@@ -463,6 +469,7 @@ public final class DefaultHlsPlaylistTracker ...@@ -463,6 +469,7 @@ public final class DefaultHlsPlaylistTracker
processLoadedPlaylist((HlsMediaPlaylist) result); processLoadedPlaylist((HlsMediaPlaylist) result);
eventDispatcher.loadCompleted( eventDispatcher.loadCompleted(
loadable.dataSpec, loadable.dataSpec,
loadable.getUri(),
C.DATA_TYPE_MANIFEST, C.DATA_TYPE_MANIFEST,
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
...@@ -480,6 +487,7 @@ public final class DefaultHlsPlaylistTracker ...@@ -480,6 +487,7 @@ public final class DefaultHlsPlaylistTracker
boolean released) { boolean released) {
eventDispatcher.loadCanceled( eventDispatcher.loadCanceled(
loadable.dataSpec, loadable.dataSpec,
loadable.getUri(),
C.DATA_TYPE_MANIFEST, C.DATA_TYPE_MANIFEST,
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
...@@ -496,6 +504,7 @@ public final class DefaultHlsPlaylistTracker ...@@ -496,6 +504,7 @@ public final class DefaultHlsPlaylistTracker
boolean isFatal = error instanceof ParserException; boolean isFatal = error instanceof ParserException;
eventDispatcher.loadError( eventDispatcher.loadError(
loadable.dataSpec, loadable.dataSpec,
loadable.getUri(),
C.DATA_TYPE_MANIFEST, C.DATA_TYPE_MANIFEST,
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
...@@ -528,7 +537,10 @@ public final class DefaultHlsPlaylistTracker ...@@ -528,7 +537,10 @@ public final class DefaultHlsPlaylistTracker
long elapsedRealtime = long elapsedRealtime =
mediaPlaylistLoader.startLoading(mediaPlaylistLoadable, this, minRetryCount); mediaPlaylistLoader.startLoading(mediaPlaylistLoadable, this, minRetryCount);
eventDispatcher.loadStarted( eventDispatcher.loadStarted(
mediaPlaylistLoadable.dataSpec, mediaPlaylistLoadable.type, elapsedRealtime); mediaPlaylistLoadable.dataSpec,
mediaPlaylistLoadable.dataSpec.uri,
mediaPlaylistLoadable.type,
elapsedRealtime);
} }
private void processLoadedPlaylist(HlsMediaPlaylist loadedPlaylist) { private void processLoadedPlaylist(HlsMediaPlaylist loadedPlaylist) {
......
...@@ -519,6 +519,7 @@ public final class SsMediaSource extends BaseMediaSource ...@@ -519,6 +519,7 @@ public final class SsMediaSource extends BaseMediaSource
long loadDurationMs) { long loadDurationMs) {
manifestEventDispatcher.loadCompleted( manifestEventDispatcher.loadCompleted(
loadable.dataSpec, loadable.dataSpec,
loadable.getUri(),
loadable.type, loadable.type,
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
...@@ -534,6 +535,7 @@ public final class SsMediaSource extends BaseMediaSource ...@@ -534,6 +535,7 @@ public final class SsMediaSource extends BaseMediaSource
long loadDurationMs, boolean released) { long loadDurationMs, boolean released) {
manifestEventDispatcher.loadCanceled( manifestEventDispatcher.loadCanceled(
loadable.dataSpec, loadable.dataSpec,
loadable.getUri(),
loadable.type, loadable.type,
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
...@@ -550,6 +552,7 @@ public final class SsMediaSource extends BaseMediaSource ...@@ -550,6 +552,7 @@ public final class SsMediaSource extends BaseMediaSource
boolean isFatal = error instanceof ParserException; boolean isFatal = error instanceof ParserException;
manifestEventDispatcher.loadError( manifestEventDispatcher.loadError(
loadable.dataSpec, loadable.dataSpec,
loadable.getUri(),
loadable.type, loadable.type,
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
...@@ -643,7 +646,8 @@ public final class SsMediaSource extends BaseMediaSource ...@@ -643,7 +646,8 @@ public final class SsMediaSource extends BaseMediaSource
ParsingLoadable<SsManifest> loadable = new ParsingLoadable<>(manifestDataSource, ParsingLoadable<SsManifest> loadable = new ParsingLoadable<>(manifestDataSource,
manifestUri, C.DATA_TYPE_MANIFEST, manifestParser); manifestUri, C.DATA_TYPE_MANIFEST, manifestParser);
long elapsedRealtimeMs = manifestLoader.startLoading(loadable, this, minLoadableRetryCount); long elapsedRealtimeMs = manifestLoader.startLoading(loadable, this, minLoadableRetryCount);
manifestEventDispatcher.loadStarted(loadable.dataSpec, loadable.type, elapsedRealtimeMs); manifestEventDispatcher.loadStarted(
loadable.dataSpec, loadable.dataSpec.uri, loadable.type, elapsedRealtimeMs);
} }
} }
...@@ -121,6 +121,7 @@ public class FakeMediaPeriod implements MediaPeriod { ...@@ -121,6 +121,7 @@ public class FakeMediaPeriod implements MediaPeriod {
public synchronized void prepare(Callback callback, long positionUs) { public synchronized void prepare(Callback callback, long positionUs) {
eventDispatcher.loadStarted( eventDispatcher.loadStarted(
FAKE_DATA_SPEC, FAKE_DATA_SPEC,
FAKE_DATA_SPEC.uri,
C.DATA_TYPE_MEDIA, C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN, C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null, /* trackFormat= */ null,
...@@ -232,6 +233,7 @@ public class FakeMediaPeriod implements MediaPeriod { ...@@ -232,6 +233,7 @@ public class FakeMediaPeriod implements MediaPeriod {
prepareCallback.onPrepared(this); prepareCallback.onPrepared(this);
eventDispatcher.loadCompleted( eventDispatcher.loadCompleted(
FAKE_DATA_SPEC, FAKE_DATA_SPEC,
FAKE_DATA_SPEC.uri,
C.DATA_TYPE_MEDIA, C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN, C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null, /* trackFormat= */ null,
......
...@@ -216,11 +216,16 @@ public class FakeMediaSource extends BaseMediaSource { ...@@ -216,11 +216,16 @@ public class FakeMediaSource extends BaseMediaSource {
EventDispatcher eventDispatcher = createEventDispatcher(/* mediaPeriodId= */ null); EventDispatcher eventDispatcher = createEventDispatcher(/* mediaPeriodId= */ null);
eventDispatcher.loadStarted( eventDispatcher.loadStarted(
new LoadEventInfo( new LoadEventInfo(
FAKE_DATA_SPEC, elapsedRealTimeMs, /* loadDurationMs= */ 0, /* bytesLoaded= */ 0), FAKE_DATA_SPEC,
FAKE_DATA_SPEC.uri,
elapsedRealTimeMs,
/* loadDurationMs= */ 0,
/* bytesLoaded= */ 0),
mediaLoadData); mediaLoadData);
eventDispatcher.loadCompleted( eventDispatcher.loadCompleted(
new LoadEventInfo( new LoadEventInfo(
FAKE_DATA_SPEC, FAKE_DATA_SPEC,
FAKE_DATA_SPEC.uri,
elapsedRealTimeMs, elapsedRealTimeMs,
/* loadDurationMs= */ 0, /* loadDurationMs= */ 0,
/* bytesLoaded= */ MANIFEST_LOAD_BYTES), /* bytesLoaded= */ MANIFEST_LOAD_BYTES),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment