Commit 7170ff38 by olly Committed by Oliver Woodman

Remove V1 DASH multi-period + seeking-in-window from V2.

Both of these features are being promoted to first class
citizens in V2 (multi-period support will be handled via
playlists, seeking-in-window will be handled by exposing
the window/timeline from the player and via the normal
seek API). For now, it's much easier to continue the
refactoring process with the features removed.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=119518675
parent 1c0a120a
......@@ -19,7 +19,6 @@ import com.google.android.exoplayer.DefaultTrackSelector.TrackInfo;
import com.google.android.exoplayer.ExoPlayer;
import com.google.android.exoplayer.Format;
import com.google.android.exoplayer.MediaCodecTrackRenderer.DecoderInitializationException;
import com.google.android.exoplayer.TimeRange;
import com.google.android.exoplayer.TrackGroup;
import com.google.android.exoplayer.TrackGroupArray;
import com.google.android.exoplayer.TrackRenderer;
......@@ -50,7 +49,6 @@ public class EventLogger implements DemoPlayer.Listener, DemoPlayer.InfoListener
}
private long sessionStartTimeMs;
private long[] availableRangeValuesUs;
public void startSession() {
sessionStartTimeMs = SystemClock.elapsedRealtime();
......@@ -215,13 +213,6 @@ public class EventLogger implements DemoPlayer.Listener, DemoPlayer.InfoListener
Log.d(TAG, "decoderInitialized [" + getSessionTimeString() + ", " + decoderName + "]");
}
@Override
public void onAvailableRangeChanged(int sourceId, TimeRange availableRange) {
availableRangeValuesUs = availableRange.getCurrentBoundsUs(availableRangeValuesUs);
Log.d(TAG, "availableRange [" + availableRange.isStatic() + ", " + availableRangeValuesUs[0]
+ ", " + availableRangeValuesUs[1] + "]");
}
private void printInternalError(String type, Exception e) {
Log.e(TAG, "internalError [" + getSessionTimeString() + ", " + type + "]", e);
}
......
......@@ -44,8 +44,6 @@ import android.os.Handler;
// TODO[REFACTOR]: Bring back UTC timing element support.
public class DashSourceBuilder implements SourceBuilder {
private static final String TAG = "DashSourceBuilder";
private static final int BUFFER_SEGMENT_SIZE = 64 * 1024;
private static final int VIDEO_BUFFER_SEGMENTS = 200;
private static final int AUDIO_BUFFER_SEGMENTS = 54;
......@@ -78,15 +76,14 @@ public class DashSourceBuilder implements SourceBuilder {
// Build the video renderer.
DataSource videoDataSource = dataSourceFactory.createDataSource(bandwidthMeter);
ChunkSource videoChunkSource = new DashChunkSource(manifestFetcher, AdaptationSet.TYPE_VIDEO,
videoDataSource, new AdaptiveEvaluator(bandwidthMeter), LIVE_EDGE_LATENCY_MS,
0, mainHandler, player, DemoPlayer.TYPE_VIDEO);
videoDataSource, new AdaptiveEvaluator(bandwidthMeter), LIVE_EDGE_LATENCY_MS);
ChunkSampleSource videoSampleSource = new ChunkSampleSource(videoChunkSource, loadControl,
VIDEO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player, DemoPlayer.TYPE_VIDEO);
// Build the audio renderer.
DataSource audioDataSource = dataSourceFactory.createDataSource(bandwidthMeter);
ChunkSource audioChunkSource = new DashChunkSource(manifestFetcher, AdaptationSet.TYPE_AUDIO,
audioDataSource, null, LIVE_EDGE_LATENCY_MS, 0, mainHandler, player, DemoPlayer.TYPE_AUDIO);
audioDataSource, null, LIVE_EDGE_LATENCY_MS);
ChunkSampleSource audioSampleSource = new ChunkSampleSource(audioChunkSource, loadControl,
AUDIO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player,
DemoPlayer.TYPE_AUDIO);
......@@ -94,7 +91,7 @@ public class DashSourceBuilder implements SourceBuilder {
// Build the text renderer.
DataSource textDataSource = dataSourceFactory.createDataSource(bandwidthMeter);
ChunkSource textChunkSource = new DashChunkSource(manifestFetcher, AdaptationSet.TYPE_TEXT,
textDataSource, null, LIVE_EDGE_LATENCY_MS, 0, mainHandler, player, DemoPlayer.TYPE_TEXT);
textDataSource, null, LIVE_EDGE_LATENCY_MS);
ChunkSampleSource textSampleSource = new ChunkSampleSource(textChunkSource, loadControl,
TEXT_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player,
DemoPlayer.TYPE_TEXT);
......
......@@ -27,12 +27,10 @@ import com.google.android.exoplayer.MediaCodecTrackRenderer.DecoderInitializatio
import com.google.android.exoplayer.MediaCodecVideoTrackRenderer;
import com.google.android.exoplayer.SampleSource;
import com.google.android.exoplayer.SingleSampleSource;
import com.google.android.exoplayer.TimeRange;
import com.google.android.exoplayer.TrackRenderer;
import com.google.android.exoplayer.audio.AudioCapabilities;
import com.google.android.exoplayer.audio.AudioTrack;
import com.google.android.exoplayer.chunk.ChunkSampleSourceEventListener;
import com.google.android.exoplayer.dash.DashChunkSource;
import com.google.android.exoplayer.drm.StreamingDrmSessionManager;
import com.google.android.exoplayer.extractor.ExtractorSampleSource;
import com.google.android.exoplayer.metadata.MetadataTrackRenderer;
......@@ -67,8 +65,8 @@ public class DemoPlayer implements ExoPlayer.Listener, DefaultTrackSelector.Even
ChunkSampleSourceEventListener, ExtractorSampleSource.EventListener,
SingleSampleSource.EventListener, DefaultBandwidthMeter.EventListener,
MediaCodecVideoTrackRenderer.EventListener, MediaCodecAudioTrackRenderer.EventListener,
StreamingDrmSessionManager.EventListener, DashChunkSource.EventListener, TextRenderer,
MetadataRenderer<List<Id3Frame>>, DebugTextViewHelper.Provider {
StreamingDrmSessionManager.EventListener, TextRenderer, MetadataRenderer<List<Id3Frame>>,
DebugTextViewHelper.Provider {
/**
* Builds a source to play.
......@@ -127,7 +125,6 @@ public class DemoPlayer implements ExoPlayer.Listener, DefaultTrackSelector.Even
long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs);
void onDecoderInitialized(String decoderName, long elapsedRealtimeMs,
long initializationDurationMs);
void onAvailableRangeChanged(int sourceId, TimeRange availableRange);
}
/**
......@@ -442,13 +439,6 @@ public class DemoPlayer implements ExoPlayer.Listener, DefaultTrackSelector.Even
}
@Override
public void onAvailableRangeChanged(int sourceId, TimeRange availableRange) {
if (infoListener != null) {
infoListener.onAvailableRangeChanged(sourceId, availableRange);
}
}
@Override
public void onPlayWhenReadyCommitted() {
// Do nothing.
}
......
/*
* Copyright (C) 2014 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.exoplayer;
import com.google.android.exoplayer.TimeRange.StaticTimeRange;
import junit.framework.TestCase;
/**
* Unit test for {@link TimeRange}.
*/
public class TimeRangeTest extends TestCase {
public void testStaticEquals() {
TimeRange timeRange1 = new StaticTimeRange(0, 30000000);
assertTrue(timeRange1.equals(timeRange1));
TimeRange timeRange2 = new StaticTimeRange(0, 30000000);
assertTrue(timeRange1.equals(timeRange2));
TimeRange timeRange3 = new StaticTimeRange(0, 60000000);
assertFalse(timeRange1.equals(timeRange3));
}
}
/*
* Copyright (C) 2014 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.exoplayer;
import com.google.android.exoplayer.util.Clock;
import android.os.SystemClock;
/**
* A container to store a start and end time in microseconds.
*/
public interface TimeRange {
/**
* Whether the range is static, meaning repeated calls to {@link #getCurrentBoundsMs(long[])}
* or {@link #getCurrentBoundsUs(long[])} will return identical results.
*
* @return Whether the range is static.
*/
public boolean isStatic();
/**
* Returns the start and end times (in milliseconds) of the TimeRange in the provided array,
* or creates a new one.
*
* @param out An array to store the start and end times; can be null.
* @return An array containing the start time (index 0) and end time (index 1) in milliseconds.
*/
public long[] getCurrentBoundsMs(long[] out);
/**
* Returns the start and end times (in microseconds) of the TimeRange in the provided array,
* or creates a new one.
*
* @param out An array to store the start and end times; can be null.
* @return An array containing the start time (index 0) and end time (index 1) in microseconds.
*/
public long[] getCurrentBoundsUs(long[] out);
/**
* A static {@link TimeRange}.
*/
public static final class StaticTimeRange implements TimeRange {
private final long startTimeUs;
private final long endTimeUs;
/**
* @param startTimeUs The beginning of the range.
* @param endTimeUs The end of the range.
*/
public StaticTimeRange(long startTimeUs, long endTimeUs) {
this.startTimeUs = startTimeUs;
this.endTimeUs = endTimeUs;
}
@Override
public boolean isStatic() {
return true;
}
@Override
public long[] getCurrentBoundsMs(long[] out) {
out = getCurrentBoundsUs(out);
out[0] /= 1000;
out[1] /= 1000;
return out;
}
@Override
public long[] getCurrentBoundsUs(long[] out) {
if (out == null || out.length < 2) {
out = new long[2];
}
out[0] = startTimeUs;
out[1] = endTimeUs;
return out;
}
@Override
public int hashCode() {
int result = 17;
result = 31 * result + (int) startTimeUs;
result = 31 * result + (int) endTimeUs;
return result;
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
StaticTimeRange other = (StaticTimeRange) obj;
return other.startTimeUs == startTimeUs
&& other.endTimeUs == endTimeUs;
}
}
/**
* A dynamic {@link TimeRange}.
*/
public static final class DynamicTimeRange implements TimeRange {
private final long minStartTimeUs;
private final long maxEndTimeUs;
private final long elapsedRealtimeAtStartUs;
private final long bufferDepthUs;
private final Clock systemClock;
/**
* @param minStartTimeUs A lower bound on the beginning of the range.
* @param maxEndTimeUs An upper bound on the end of the range.
* @param elapsedRealtimeAtStartUs The value of {@link SystemClock#elapsedRealtime()},
* multiplied by 1000, corresponding to a media time of zero.
* @param bufferDepthUs The buffer depth of the media, or -1.
* @param systemClock A system clock.
*/
public DynamicTimeRange(long minStartTimeUs, long maxEndTimeUs, long elapsedRealtimeAtStartUs,
long bufferDepthUs, Clock systemClock) {
this.minStartTimeUs = minStartTimeUs;
this.maxEndTimeUs = maxEndTimeUs;
this.elapsedRealtimeAtStartUs = elapsedRealtimeAtStartUs;
this.bufferDepthUs = bufferDepthUs;
this.systemClock = systemClock;
}
@Override
public boolean isStatic() {
return false;
}
@Override
public long[] getCurrentBoundsMs(long[] out) {
out = getCurrentBoundsUs(out);
out[0] /= 1000;
out[1] /= 1000;
return out;
}
@Override
public long[] getCurrentBoundsUs(long[] out) {
if (out == null || out.length < 2) {
out = new long[2];
}
// Don't allow the end time to be greater than the total elapsed time.
long currentEndTimeUs = Math.min(maxEndTimeUs,
(systemClock.elapsedRealtime() * 1000) - elapsedRealtimeAtStartUs);
long currentStartTimeUs = minStartTimeUs;
if (bufferDepthUs != -1) {
// Don't allow the start time to be less than the current end time minus the buffer depth.
currentStartTimeUs = Math.max(currentStartTimeUs,
currentEndTimeUs - bufferDepthUs);
}
out[0] = currentStartTimeUs;
out[1] = currentEndTimeUs;
return out;
}
@Override
public int hashCode() {
int result = 17;
result = 31 * result + (int) minStartTimeUs;
result = 31 * result + (int) maxEndTimeUs;
result = 31 * result + (int) elapsedRealtimeAtStartUs;
result = 31 * result + (int) bufferDepthUs;
return result;
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
DynamicTimeRange other = (DynamicTimeRange) obj;
return other.minStartTimeUs == minStartTimeUs
&& other.maxEndTimeUs == maxEndTimeUs
&& other.elapsedRealtimeAtStartUs == elapsedRealtimeAtStartUs
&& other.bufferDepthUs == bufferDepthUs;
}
}
}
......@@ -50,11 +50,10 @@ public abstract class BaseMediaChunk extends MediaChunk {
* 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.
* @param parentId Identifier for a parent from which this chunk originates.
*/
public BaseMediaChunk(DataSource dataSource, DataSpec dataSpec, int trigger, Format format,
long startTimeUs, long endTimeUs, int chunkIndex, boolean isSampleFormatFinal, int parentId) {
super(dataSource, dataSpec, trigger, format, startTimeUs, endTimeUs, chunkIndex, parentId);
long startTimeUs, long endTimeUs, int chunkIndex, boolean isSampleFormatFinal) {
super(dataSource, dataSpec, trigger, format, startTimeUs, endTimeUs, chunkIndex);
this.isSampleFormatFinal = isSampleFormatFinal;
}
......
......@@ -76,10 +76,6 @@ public abstract class Chunk implements Loadable {
* Implementations may define custom {@link #trigger} codes greater than or equal to this value.
*/
public static final int TRIGGER_CUSTOM_BASE = 10000;
/**
* Value of {@link #parentId} if no parent id need be specified.
*/
public static final int NO_PARENT_ID = -1;
/**
* The type of the chunk. For reporting only.
......@@ -98,10 +94,6 @@ public abstract class Chunk implements Loadable {
* The {@link DataSpec} that defines the data to be loaded.
*/
public final DataSpec dataSpec;
/**
* Optional identifier for a parent from which this chunk originates.
*/
public final int parentId;
protected final DataSource dataSource;
......@@ -114,16 +106,13 @@ public abstract class Chunk implements Loadable {
* @param type See {@link #type}.
* @param trigger See {@link #trigger}.
* @param format See {@link #format}.
* @param parentId See {@link #parentId}.
*/
public Chunk(DataSource dataSource, DataSpec dataSpec, int type, int trigger, Format format,
int parentId) {
public Chunk(DataSource dataSource, DataSpec dataSpec, int type, int trigger, Format format) {
this.dataSource = Assertions.checkNotNull(dataSource);
this.dataSpec = Assertions.checkNotNull(dataSpec);
this.type = type;
this.trigger = trigger;
this.format = format;
this.parentId = parentId;
}
/**
......
......@@ -60,14 +60,13 @@ public class ContainerMediaChunk extends BaseMediaChunk implements SingleTrackOu
* @param isSampleFormatFinal True if {@code sampleFormat} and {@code drmInitData} are known to be
* correct and final. False if the data may define its own sample format or initialization
* data.
* @param parentId Identifier for a parent from which this chunk originates.
*/
public ContainerMediaChunk(DataSource dataSource, DataSpec dataSpec, int trigger, Format format,
long startTimeUs, long endTimeUs, int chunkIndex, long sampleOffsetUs,
ChunkExtractorWrapper extractorWrapper, Format sampleFormat, DrmInitData drmInitData,
boolean isSampleFormatFinal, int parentId) {
boolean isSampleFormatFinal) {
super(dataSource, dataSpec, trigger, format, startTimeUs, endTimeUs, chunkIndex,
isSampleFormatFinal, parentId);
isSampleFormatFinal);
this.extractorWrapper = extractorWrapper;
this.sampleOffsetUs = sampleOffsetUs;
this.sampleFormat = getAdjustedSampleFormat(sampleFormat, sampleOffsetUs);
......
......@@ -44,12 +44,11 @@ public abstract class DataChunk extends Chunk {
* @param type See {@link #type}.
* @param trigger See {@link #trigger}.
* @param format See {@link #format}.
* @param parentId Identifier for a parent from which this chunk originates.
* @param data An optional recycled array that can be used as a holder for the data.
*/
public DataChunk(DataSource dataSource, DataSpec dataSpec, int type, int trigger, Format format,
int parentId, byte[] data) {
super(dataSource, dataSpec, type, trigger, format, parentId);
byte[] data) {
super(dataSource, dataSpec, type, trigger, format);
this.data = data;
}
......
......@@ -46,11 +46,6 @@ public final class InitializationChunk extends Chunk implements SingleTrackOutpu
private volatile int bytesLoaded;
private volatile boolean loadCanceled;
public InitializationChunk(DataSource dataSource, DataSpec dataSpec, int trigger, Format format,
ChunkExtractorWrapper extractorWrapper) {
this(dataSource, dataSpec, trigger, format, extractorWrapper, Chunk.NO_PARENT_ID);
}
/**
* Constructor for a chunk of media samples.
*
......@@ -59,11 +54,10 @@ public final class InitializationChunk extends Chunk implements SingleTrackOutpu
* @param trigger The reason for this chunk being selected.
* @param format The format of the stream to which this chunk belongs.
* @param extractorWrapper A wrapped extractor to use for parsing the initialization data.
* @param parentId Identifier for a parent from which this chunk originates.
*/
public InitializationChunk(DataSource dataSource, DataSpec dataSpec, int trigger, Format format,
ChunkExtractorWrapper extractorWrapper, int parentId) {
super(dataSource, dataSpec, Chunk.TYPE_MEDIA_INITIALIZATION, trigger, format, parentId);
ChunkExtractorWrapper extractorWrapper) {
super(dataSource, dataSpec, Chunk.TYPE_MEDIA_INITIALIZATION, trigger, format);
this.extractorWrapper = extractorWrapper;
}
......
......@@ -38,16 +38,6 @@ public abstract class MediaChunk extends Chunk {
*/
public final int chunkIndex;
public MediaChunk(DataSource dataSource, DataSpec dataSpec, int trigger, Format format,
long startTimeUs, long endTimeUs, int chunkIndex) {
this(dataSource, dataSpec, trigger, format, startTimeUs, endTimeUs, chunkIndex,
Chunk.NO_PARENT_ID);
}
public int getNextChunkIndex() {
return chunkIndex + 1;
}
/**
* @param dataSource A {@link DataSource} for loading the data.
* @param dataSpec Defines the data to be loaded.
......@@ -56,15 +46,18 @@ public abstract class MediaChunk extends Chunk {
* @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 parentId Identifier for a parent from which this chunk originates.
*/
public MediaChunk(DataSource dataSource, DataSpec dataSpec, int trigger, Format format,
long startTimeUs, long endTimeUs, int chunkIndex, int parentId) {
super(dataSource, dataSpec, Chunk.TYPE_MEDIA, trigger, format, parentId);
long startTimeUs, long endTimeUs, int chunkIndex) {
super(dataSource, dataSpec, Chunk.TYPE_MEDIA, trigger, format);
Assertions.checkNotNull(format);
this.startTimeUs = startTimeUs;
this.endTimeUs = endTimeUs;
this.chunkIndex = chunkIndex;
}
public final int getNextChunkIndex() {
return chunkIndex + 1;
}
}
......@@ -48,13 +48,11 @@ public final class SingleSampleMediaChunk extends BaseMediaChunk {
* @param sampleFormat The format of the sample.
* @param sampleDrmInitData The {@link DrmInitData} for the sample. Null if the sample is not drm
* protected.
* @param parentId Identifier for a parent from which this chunk originates.
*/
public SingleSampleMediaChunk(DataSource dataSource, DataSpec dataSpec, int trigger,
Format format, long startTimeUs, long endTimeUs, int chunkIndex, Format sampleFormat,
DrmInitData sampleDrmInitData, int parentId) {
super(dataSource, dataSpec, trigger, format, startTimeUs, endTimeUs, chunkIndex, true,
parentId);
DrmInitData sampleDrmInitData) {
super(dataSource, dataSpec, trigger, format, startTimeUs, endTimeUs, chunkIndex, true);
this.sampleFormat = sampleFormat;
this.sampleDrmInitData = sampleDrmInitData;
}
......
......@@ -727,7 +727,7 @@ public class HlsChunkSource {
byte[] scratchSpace, HlsPlaylistParser playlistParser, int variantIndex,
Uri playlistUri) {
super(dataSource, dataSpec, Chunk.TYPE_MANIFEST, Chunk.TRIGGER_UNSPECIFIED, format,
Chunk.NO_PARENT_ID, scratchSpace);
scratchSpace);
this.variantIndex = variantIndex;
this.playlistParser = playlistParser;
this.playlistUri = playlistUri;
......@@ -754,7 +754,7 @@ public class HlsChunkSource {
public EncryptionKeyChunk(DataSource dataSource, DataSpec dataSpec, Format format,
byte[] scratchSpace, String iv) {
super(dataSource, dataSpec, Chunk.TYPE_DRM, Chunk.TRIGGER_UNSPECIFIED, format,
Chunk.NO_PARENT_ID, scratchSpace);
scratchSpace);
this.iv = iv;
}
......
......@@ -253,7 +253,7 @@ public class SmoothStreamingChunkSource implements ChunkSource {
}
chunkIndex = streamElement.getChunkIndex(playbackPositionUs);
} else {
chunkIndex = previous.chunkIndex + 1 - currentManifestChunkOffset;
chunkIndex = previous.getNextChunkIndex() - currentManifestChunkOffset;
}
if (live && chunkIndex < 0) {
......@@ -404,7 +404,7 @@ public class SmoothStreamingChunkSource implements ChunkSource {
long sampleOffsetUs = chunkStartTimeUs;
return new ContainerMediaChunk(dataSource, dataSpec, trigger, format, chunkStartTimeUs,
chunkEndTimeUs, chunkIndex, sampleOffsetUs, extractorWrapper, sampleFormat, drmInitData,
true, Chunk.NO_PARENT_ID);
true);
}
private static byte[] getProtectionElementKeyId(byte[] initData) {
......
......@@ -16,11 +16,10 @@
package com.google.android.exoplayer.upstream;
import com.google.android.exoplayer.util.Assertions;
import com.google.android.exoplayer.util.Clock;
import com.google.android.exoplayer.util.SlidingPercentile;
import com.google.android.exoplayer.util.SystemClock;
import android.os.Handler;
import android.os.SystemClock;
/**
* Counts transferred bytes while transfers are open and creates a bandwidth sample and updated
......@@ -35,7 +34,6 @@ public final class DefaultBandwidthMeter implements BandwidthMeter {
private final Handler eventHandler;
private final EventListener eventListener;
private final Clock clock;
private final SlidingPercentile slidingPercentile;
private int streamCount;
......@@ -51,22 +49,12 @@ public final class DefaultBandwidthMeter implements BandwidthMeter {
}
public DefaultBandwidthMeter(Handler eventHandler, EventListener eventListener) {
this(eventHandler, eventListener, new SystemClock());
}
public DefaultBandwidthMeter(Handler eventHandler, EventListener eventListener, Clock clock) {
this(eventHandler, eventListener, clock, DEFAULT_MAX_WEIGHT);
this(eventHandler, eventListener, DEFAULT_MAX_WEIGHT);
}
public DefaultBandwidthMeter(Handler eventHandler, EventListener eventListener, int maxWeight) {
this(eventHandler, eventListener, new SystemClock(), maxWeight);
}
public DefaultBandwidthMeter(Handler eventHandler, EventListener eventListener, Clock clock,
int maxWeight) {
this.eventHandler = eventHandler;
this.eventListener = eventListener;
this.clock = clock;
this.slidingPercentile = new SlidingPercentile(maxWeight);
bitrateEstimate = NO_ESTIMATE;
}
......@@ -79,7 +67,7 @@ public final class DefaultBandwidthMeter implements BandwidthMeter {
@Override
public synchronized void onTransferStart() {
if (streamCount == 0) {
sampleStartTimeMs = clock.elapsedRealtime();
sampleStartTimeMs = SystemClock.elapsedRealtime();
}
streamCount++;
}
......@@ -92,7 +80,7 @@ public final class DefaultBandwidthMeter implements BandwidthMeter {
@Override
public synchronized void onTransferEnd() {
Assertions.checkState(streamCount > 0);
long nowMs = clock.elapsedRealtime();
long nowMs = SystemClock.elapsedRealtime();
int sampleElapsedTimeMs = (int) (nowMs - sampleStartTimeMs);
totalElapsedTimeMs += sampleElapsedTimeMs;
totalBytesTransferred += sampleBytesTransferred;
......
/*
* Copyright (C) 2014 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.exoplayer.util;
/**
* The standard implementation of {@link Clock}.
*/
public final class SystemClock implements Clock {
@Override
public long elapsedRealtime() {
return android.os.SystemClock.elapsedRealtime();
}
}
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