Make SampleSources reusable and implement SampleSourceProvider.
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=126888556
This commit is contained in:
parent
42d78b3559
commit
af3452d231
@ -30,18 +30,24 @@ import com.google.android.exoplayer.MediaCodecUtil.DecoderQueryException;
|
||||
import com.google.android.exoplayer.SampleSourceProvider;
|
||||
import com.google.android.exoplayer.SimpleExoPlayer;
|
||||
import com.google.android.exoplayer.TrackGroupArray;
|
||||
import com.google.android.exoplayer.dash.DashSampleSource;
|
||||
import com.google.android.exoplayer.drm.DrmSessionManager;
|
||||
import com.google.android.exoplayer.drm.StreamingDrmSessionManager;
|
||||
import com.google.android.exoplayer.drm.UnsupportedDrmException;
|
||||
import com.google.android.exoplayer.extractor.DefaultExtractorsFactory;
|
||||
import com.google.android.exoplayer.extractor.ExtractorSampleSource;
|
||||
import com.google.android.exoplayer.hls.HlsSampleSource;
|
||||
import com.google.android.exoplayer.metadata.id3.ApicFrame;
|
||||
import com.google.android.exoplayer.metadata.id3.GeobFrame;
|
||||
import com.google.android.exoplayer.metadata.id3.Id3Frame;
|
||||
import com.google.android.exoplayer.metadata.id3.PrivFrame;
|
||||
import com.google.android.exoplayer.metadata.id3.TextInformationFrame;
|
||||
import com.google.android.exoplayer.metadata.id3.TxxxFrame;
|
||||
import com.google.android.exoplayer.smoothstreaming.SmoothStreamingSampleSource;
|
||||
import com.google.android.exoplayer.text.CaptionStyleCompat;
|
||||
import com.google.android.exoplayer.text.Cue;
|
||||
import com.google.android.exoplayer.text.SubtitleLayout;
|
||||
import com.google.android.exoplayer.upstream.BandwidthMeter;
|
||||
import com.google.android.exoplayer.upstream.DataSourceFactory;
|
||||
import com.google.android.exoplayer.upstream.DefaultDataSourceFactory;
|
||||
import com.google.android.exoplayer.util.DebugTextViewHelper;
|
||||
@ -57,6 +63,7 @@ import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
@ -126,6 +133,7 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
|
||||
private DefaultTrackSelector trackSelector;
|
||||
private TrackSelectionHelper trackSelectionHelper;
|
||||
private DebugTextViewHelper debugViewHelper;
|
||||
private BandwidthMeter bandwidthMeter;
|
||||
private boolean playerNeedsSource;
|
||||
|
||||
private long playerPosition;
|
||||
@ -283,6 +291,7 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
|
||||
mediaController.setAnchorView(rootView);
|
||||
debugViewHelper = new DebugTextViewHelper(player, debugTextView);
|
||||
debugViewHelper.start();
|
||||
bandwidthMeter = player.getBandwidthMeter();
|
||||
playerNeedsSource = true;
|
||||
}
|
||||
if (playerNeedsSource) {
|
||||
@ -311,10 +320,9 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
|
||||
return;
|
||||
}
|
||||
|
||||
UriSampleSourceProvider[] providers = new UriSampleSourceProvider[uris.length];
|
||||
SampleSourceProvider[] providers = new SampleSourceProvider[uris.length];
|
||||
for (int i = 0; i < uris.length; i++) {
|
||||
providers[i] = new UriSampleSourceProvider(player.getBandwidthMeter(), dataSourceFactory,
|
||||
uris[i], extensions[i], mainHandler, eventLogger);
|
||||
providers[i] = getSampleSourceProvider(uris[i], extensions[i]);
|
||||
}
|
||||
SampleSourceProvider sourceProvider = providers.length == 1 ? providers[0]
|
||||
: new ConcatenatingSampleSourceProvider(providers);
|
||||
@ -324,6 +332,28 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
|
||||
}
|
||||
}
|
||||
|
||||
private SampleSourceProvider getSampleSourceProvider(Uri uri, String overrideExtension) {
|
||||
String lastPathSegment = !TextUtils.isEmpty(overrideExtension) ? "." + overrideExtension
|
||||
: uri.getLastPathSegment();
|
||||
int type = Util.inferContentType(lastPathSegment);
|
||||
switch (type) {
|
||||
case Util.TYPE_SS:
|
||||
return new SmoothStreamingSampleSource(uri, dataSourceFactory, bandwidthMeter, mainHandler,
|
||||
eventLogger);
|
||||
case Util.TYPE_DASH:
|
||||
return new DashSampleSource(uri, dataSourceFactory, bandwidthMeter, mainHandler,
|
||||
eventLogger);
|
||||
case Util.TYPE_HLS:
|
||||
return new HlsSampleSource(uri, dataSourceFactory, bandwidthMeter, mainHandler,
|
||||
eventLogger);
|
||||
case Util.TYPE_OTHER:
|
||||
return new ExtractorSampleSource(uri, dataSourceFactory, bandwidthMeter,
|
||||
new DefaultExtractorsFactory(), mainHandler, eventLogger);
|
||||
default:
|
||||
throw new IllegalStateException("Unsupported type: " + type);
|
||||
}
|
||||
}
|
||||
|
||||
private DrmSessionManager buildDrmSessionManager(UUID uuid, String id, String provider)
|
||||
throws UnsupportedDrmException {
|
||||
if (Util.SDK_INT < 18) {
|
||||
|
@ -1,105 +0,0 @@
|
||||
/*
|
||||
* 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.demo;
|
||||
|
||||
import com.google.android.exoplayer.SampleSource;
|
||||
import com.google.android.exoplayer.SampleSourceProvider;
|
||||
import com.google.android.exoplayer.dash.DashSampleSource;
|
||||
import com.google.android.exoplayer.extractor.DefaultExtractorsFactory;
|
||||
import com.google.android.exoplayer.extractor.ExtractorSampleSource;
|
||||
import com.google.android.exoplayer.hls.HlsSampleSource;
|
||||
import com.google.android.exoplayer.smoothstreaming.SmoothStreamingSampleSource;
|
||||
import com.google.android.exoplayer.upstream.BandwidthMeter;
|
||||
import com.google.android.exoplayer.upstream.DataSourceFactory;
|
||||
import com.google.android.exoplayer.util.Util;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.text.TextUtils;
|
||||
|
||||
/**
|
||||
* Provides a {@link SampleSource} to play back media loaded from a {@link Uri}.
|
||||
*/
|
||||
public final class UriSampleSourceProvider implements SampleSourceProvider {
|
||||
|
||||
private final BandwidthMeter bandwidthMeter;
|
||||
private final DataSourceFactory dataSourceFactory;
|
||||
private final Uri uri;
|
||||
private final String overrideExtension;
|
||||
private final Handler handler;
|
||||
private final EventLogger eventLogger;
|
||||
|
||||
/**
|
||||
* Constructs a source provider for {@link SampleSource} to play back media at the specified
|
||||
* URI, using the specified type.
|
||||
*
|
||||
* @param bandwidthMeter A bandwidth meter.
|
||||
* @param dataSourceFactory A data source factory.
|
||||
* @param uri The URI to play back.
|
||||
* @param overrideExtension An overriding file extension used when inferring the source's type,
|
||||
* or {@code null}.
|
||||
* @param handler A handler to use for logging events.
|
||||
* @param eventLogger An event logger.
|
||||
*/
|
||||
public UriSampleSourceProvider(BandwidthMeter bandwidthMeter, DataSourceFactory dataSourceFactory,
|
||||
Uri uri, String overrideExtension, Handler handler, EventLogger eventLogger) {
|
||||
this.bandwidthMeter = bandwidthMeter;
|
||||
this.dataSourceFactory = dataSourceFactory;
|
||||
this.uri = uri;
|
||||
this.overrideExtension = overrideExtension;
|
||||
this.handler = handler;
|
||||
this.eventLogger = eventLogger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSourceCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SampleSource createSource(int index) {
|
||||
int type = inferContentType(uri, overrideExtension);
|
||||
switch (type) {
|
||||
case Util.TYPE_SS:
|
||||
return new SmoothStreamingSampleSource(uri, dataSourceFactory, bandwidthMeter, handler,
|
||||
eventLogger);
|
||||
case Util.TYPE_DASH:
|
||||
return new DashSampleSource(uri, dataSourceFactory, bandwidthMeter, handler, eventLogger);
|
||||
case Util.TYPE_HLS:
|
||||
return new HlsSampleSource(uri, dataSourceFactory, bandwidthMeter, handler, eventLogger);
|
||||
case Util.TYPE_OTHER:
|
||||
return new ExtractorSampleSource(uri, dataSourceFactory, bandwidthMeter,
|
||||
new DefaultExtractorsFactory(), handler, eventLogger);
|
||||
default:
|
||||
throw new IllegalStateException("Unsupported type: " + type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a best guess to infer the type from a media {@link Uri} and an optional overriding file
|
||||
* extension.
|
||||
*
|
||||
* @param uri The {@link Uri} of the media.
|
||||
* @param fileExtension An overriding file extension.
|
||||
* @return The inferred type.
|
||||
*/
|
||||
private static int inferContentType(Uri uri, String fileExtension) {
|
||||
String lastPathSegment = !TextUtils.isEmpty(fileExtension) ? "." + fileExtension
|
||||
: uri.getLastPathSegment();
|
||||
return Util.inferContentType(lastPathSegment);
|
||||
}
|
||||
|
||||
}
|
@ -83,7 +83,7 @@ public class FlacPlaybackTest extends InstrumentationTestCase {
|
||||
new MatroskaExtractor.Factory(),
|
||||
null,
|
||||
null);
|
||||
player.setSource(sampleSource);
|
||||
player.setSourceProvider(sampleSource);
|
||||
player.setPlayWhenReady(true);
|
||||
Looper.loop();
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ public class OpusPlaybackTest extends InstrumentationTestCase {
|
||||
new MatroskaExtractor.Factory(),
|
||||
null,
|
||||
null);
|
||||
player.setSource(sampleSource);
|
||||
player.setSourceProvider(sampleSource);
|
||||
player.setPlayWhenReady(true);
|
||||
Looper.loop();
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ public class VpxPlaybackTest extends InstrumentationTestCase {
|
||||
player.sendMessages(new ExoPlayer.ExoPlayerMessage(videoRenderer,
|
||||
LibvpxVideoTrackRenderer.MSG_SET_OUTPUT_BUFFER_RENDERER,
|
||||
new VpxVideoSurfaceView(context)));
|
||||
player.setSource(sampleSource);
|
||||
player.setSourceProvider(sampleSource);
|
||||
player.setPlayWhenReady(true);
|
||||
Looper.loop();
|
||||
}
|
||||
|
@ -235,14 +235,6 @@ public interface ExoPlayer {
|
||||
*/
|
||||
int getPlaybackState();
|
||||
|
||||
/**
|
||||
* Sets the player's source. The player will transition to {@link #STATE_BUFFERING} until it is
|
||||
* ready to play the new source.
|
||||
*
|
||||
* @param sampleSource The {@link SampleSource} to play.
|
||||
*/
|
||||
void setSource(SampleSource sampleSource);
|
||||
|
||||
/**
|
||||
* Sets the player's source provider. The player's position will be reset to the start of the
|
||||
* first source and the player will transition to {@link #STATE_BUFFERING} until it is ready to
|
||||
|
@ -93,11 +93,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
return playbackState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSource(final SampleSource sampleSource) {
|
||||
setSourceProvider(new SingleSampleSourceProvider(sampleSource));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSourceProvider(SampleSourceProvider sourceProvider) {
|
||||
maskingSourceIndex = 0;
|
||||
@ -267,25 +262,4 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class SingleSampleSourceProvider implements SampleSourceProvider {
|
||||
|
||||
private final SampleSource sampleSource;
|
||||
|
||||
public SingleSampleSourceProvider(SampleSource sampleSource) {
|
||||
this.sampleSource = sampleSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSourceCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SampleSource createSource(int index) {
|
||||
// The source will only be created once.
|
||||
return sampleSource;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -313,11 +313,6 @@ public final class SimpleExoPlayer implements ExoPlayer {
|
||||
return player.getPlaybackState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSource(SampleSource sampleSource) {
|
||||
player.setSource(sampleSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSourceProvider(SampleSourceProvider sourceProvider) {
|
||||
player.setSourceProvider(sourceProvider);
|
||||
|
@ -17,6 +17,7 @@ package com.google.android.exoplayer;
|
||||
|
||||
import com.google.android.exoplayer.upstream.Allocator;
|
||||
import com.google.android.exoplayer.upstream.DataSource;
|
||||
import com.google.android.exoplayer.upstream.DataSourceFactory;
|
||||
import com.google.android.exoplayer.upstream.DataSpec;
|
||||
import com.google.android.exoplayer.upstream.Loader;
|
||||
import com.google.android.exoplayer.upstream.Loader.Loadable;
|
||||
@ -30,10 +31,11 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A {@link SampleSource} that loads the data at a given {@link Uri} as a single sample.
|
||||
* A {@link SampleSource} that loads the data at a given {@link Uri} as a single sample. Also acts
|
||||
* as a {@link SampleSourceProvider} providing {@link SingleSampleSource} instances.
|
||||
*/
|
||||
public final class SingleSampleSource implements SampleSource, TrackStream,
|
||||
Loader.Callback<SingleSampleSource>, Loadable {
|
||||
public final class SingleSampleSource implements SampleSource, SampleSourceProvider, TrackStream,
|
||||
Loader.Callback<SingleSampleSource.SourceLoadable> {
|
||||
|
||||
/**
|
||||
* Interface definition for a callback to be notified of {@link SingleSampleSource} events.
|
||||
@ -65,8 +67,7 @@ public final class SingleSampleSource implements SampleSource, TrackStream,
|
||||
private static final int STREAM_STATE_END_OF_STREAM = 2;
|
||||
|
||||
private final Uri uri;
|
||||
private final DataSource dataSource;
|
||||
private final Loader loader;
|
||||
private final DataSourceFactory dataSourceFactory;
|
||||
private final Format format;
|
||||
private final long durationUs;
|
||||
private final int minLoadableRetryCount;
|
||||
@ -75,41 +76,57 @@ public final class SingleSampleSource implements SampleSource, TrackStream,
|
||||
private final EventListener eventListener;
|
||||
private final int eventSourceId;
|
||||
|
||||
private Loader loader;
|
||||
private boolean loadingFinished;
|
||||
|
||||
private int streamState;
|
||||
private byte[] sampleData;
|
||||
private int sampleSize;
|
||||
|
||||
public SingleSampleSource(Uri uri, DataSource dataSource, Format format, long durationUs) {
|
||||
this(uri, dataSource, format, durationUs, DEFAULT_MIN_LOADABLE_RETRY_COUNT);
|
||||
public SingleSampleSource(Uri uri, DataSourceFactory dataSourceFactory, Format format,
|
||||
long durationUs) {
|
||||
this(uri, dataSourceFactory, format, durationUs, DEFAULT_MIN_LOADABLE_RETRY_COUNT);
|
||||
}
|
||||
|
||||
public SingleSampleSource(Uri uri, DataSource dataSource, Format format, long durationUs,
|
||||
int minLoadableRetryCount) {
|
||||
this(uri, dataSource, format, durationUs, minLoadableRetryCount, null, null, 0);
|
||||
public SingleSampleSource(Uri uri, DataSourceFactory dataSourceFactory, Format format,
|
||||
long durationUs, int minLoadableRetryCount) {
|
||||
this(uri, dataSourceFactory, format, durationUs, minLoadableRetryCount, null, null, 0);
|
||||
}
|
||||
|
||||
public SingleSampleSource(Uri uri, DataSource dataSource, Format format, long durationUs,
|
||||
int minLoadableRetryCount, Handler eventHandler, EventListener eventListener,
|
||||
public SingleSampleSource(Uri uri, DataSourceFactory dataSourceFactory, Format format,
|
||||
long durationUs, int minLoadableRetryCount, Handler eventHandler, EventListener eventListener,
|
||||
int eventSourceId) {
|
||||
this.uri = uri;
|
||||
this.dataSource = dataSource;
|
||||
this.dataSourceFactory = dataSourceFactory;
|
||||
this.format = format;
|
||||
this.durationUs = durationUs;
|
||||
this.minLoadableRetryCount = minLoadableRetryCount;
|
||||
this.eventHandler = eventHandler;
|
||||
this.eventListener = eventListener;
|
||||
this.eventSourceId = eventSourceId;
|
||||
loader = new Loader("Loader:SingleSampleSource");
|
||||
tracks = new TrackGroupArray(new TrackGroup(format));
|
||||
sampleData = new byte[INITIAL_SAMPLE_SIZE];
|
||||
streamState = STREAM_STATE_SEND_FORMAT;
|
||||
}
|
||||
|
||||
// SampleSourceProvider implementation.
|
||||
|
||||
@Override
|
||||
public int getSourceCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SampleSource createSource(int index) {
|
||||
Assertions.checkArgument(index == 0);
|
||||
return this;
|
||||
}
|
||||
|
||||
// SampleSource implementation.
|
||||
|
||||
@Override
|
||||
public void prepare(Callback callback, Allocator allocator, long positionUs) {
|
||||
loader = new Loader("Loader:SingleSampleSource");
|
||||
callback.onSourcePrepared(this);
|
||||
}
|
||||
|
||||
@ -147,7 +164,8 @@ public final class SingleSampleSource implements SampleSource, TrackStream,
|
||||
if (loadingFinished || loader.isLoading()) {
|
||||
return false;
|
||||
}
|
||||
loader.startLoading(this, this, minLoadableRetryCount);
|
||||
loader.startLoading(new SourceLoadable(uri, dataSourceFactory.createDataSource()), this,
|
||||
minLoadableRetryCount);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -171,8 +189,14 @@ public final class SingleSampleSource implements SampleSource, TrackStream,
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
if (loader != null) {
|
||||
loader.release();
|
||||
loader = null;
|
||||
}
|
||||
loadingFinished = false;
|
||||
streamState = STREAM_STATE_SEND_FORMAT;
|
||||
sampleData = null;
|
||||
loader.release();
|
||||
sampleSize = 0;
|
||||
}
|
||||
|
||||
// TrackStream implementation.
|
||||
@ -219,57 +243,26 @@ public final class SingleSampleSource implements SampleSource, TrackStream,
|
||||
// Loader.Callback implementation.
|
||||
|
||||
@Override
|
||||
public void onLoadCompleted(SingleSampleSource loadable, long elapsedRealtimeMs,
|
||||
public void onLoadCompleted(SourceLoadable loadable, long elapsedRealtimeMs,
|
||||
long loadDurationMs) {
|
||||
sampleSize = loadable.sampleSize;
|
||||
sampleData = loadable.sampleData;
|
||||
loadingFinished = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadCanceled(SingleSampleSource loadable, long elapsedRealtimeMs,
|
||||
long loadDurationMs, boolean released) {
|
||||
// Never happens.
|
||||
public void onLoadCanceled(SourceLoadable loadable, long elapsedRealtimeMs, long loadDurationMs,
|
||||
boolean released) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onLoadError(SingleSampleSource loadable, long elapsedRealtimeMs,
|
||||
long loadDurationMs, IOException error) {
|
||||
public int onLoadError(SourceLoadable loadable, long elapsedRealtimeMs, long loadDurationMs,
|
||||
IOException error) {
|
||||
notifyLoadError(error);
|
||||
return Loader.RETRY;
|
||||
}
|
||||
|
||||
// Loadable implementation.
|
||||
|
||||
@Override
|
||||
public void cancelLoad() {
|
||||
// Never happens.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoadCanceled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() throws IOException, InterruptedException {
|
||||
// We always load from the beginning, so reset the sampleSize to 0.
|
||||
sampleSize = 0;
|
||||
try {
|
||||
// Create and open the input.
|
||||
dataSource.open(new DataSpec(uri));
|
||||
// Load the sample data.
|
||||
int result = 0;
|
||||
while (result != C.RESULT_END_OF_INPUT) {
|
||||
sampleSize += result;
|
||||
if (sampleSize == sampleData.length) {
|
||||
sampleData = Arrays.copyOf(sampleData, sampleData.length * 2);
|
||||
}
|
||||
result = dataSource.read(sampleData, sampleSize, sampleData.length - sampleSize);
|
||||
}
|
||||
} finally {
|
||||
dataSource.close();
|
||||
}
|
||||
}
|
||||
|
||||
// Internal methods.
|
||||
|
||||
private void notifyLoadError(final IOException e) {
|
||||
@ -283,4 +276,50 @@ public final class SingleSampleSource implements SampleSource, TrackStream,
|
||||
}
|
||||
}
|
||||
|
||||
/* package */ static final class SourceLoadable implements Loadable {
|
||||
|
||||
private final Uri uri;
|
||||
private final DataSource dataSource;
|
||||
|
||||
private int sampleSize;
|
||||
private byte[] sampleData;
|
||||
|
||||
public SourceLoadable(Uri uri, DataSource dataSource) {
|
||||
this.uri = uri;
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelLoad() {
|
||||
// Never happens.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoadCanceled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() throws IOException, InterruptedException {
|
||||
// We always load from the beginning, so reset the sampleSize to 0.
|
||||
sampleSize = 0;
|
||||
try {
|
||||
// Create and open the input.
|
||||
dataSource.open(new DataSpec(uri));
|
||||
// Load the sample data.
|
||||
int result = 0;
|
||||
while (result != C.RESULT_END_OF_INPUT) {
|
||||
sampleSize += result;
|
||||
if (sampleSize == sampleData.length) {
|
||||
sampleData = Arrays.copyOf(sampleData, sampleData.length * 2);
|
||||
}
|
||||
result = dataSource.read(sampleData, sampleSize, sampleData.length - sampleSize);
|
||||
}
|
||||
} finally {
|
||||
dataSource.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import com.google.android.exoplayer.CompositeSequenceableLoader;
|
||||
import com.google.android.exoplayer.Format;
|
||||
import com.google.android.exoplayer.ParserException;
|
||||
import com.google.android.exoplayer.SampleSource;
|
||||
import com.google.android.exoplayer.SampleSourceProvider;
|
||||
import com.google.android.exoplayer.SequenceableLoader;
|
||||
import com.google.android.exoplayer.TrackGroup;
|
||||
import com.google.android.exoplayer.TrackGroupArray;
|
||||
@ -42,6 +43,7 @@ import com.google.android.exoplayer.upstream.DataSource;
|
||||
import com.google.android.exoplayer.upstream.DataSourceFactory;
|
||||
import com.google.android.exoplayer.upstream.Loader;
|
||||
import com.google.android.exoplayer.upstream.ParsingLoadable;
|
||||
import com.google.android.exoplayer.util.Assertions;
|
||||
import com.google.android.exoplayer.util.Util;
|
||||
|
||||
import android.net.Uri;
|
||||
@ -61,9 +63,10 @@ import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* A {@link SampleSource} for DASH media.
|
||||
* A {@link SampleSource} for DASH media. Also acts as a {@link SampleSourceProvider} providing
|
||||
* {@link DashSampleSource} instances.
|
||||
*/
|
||||
public final class DashSampleSource implements SampleSource,
|
||||
public final class DashSampleSource implements SampleSource, SampleSourceProvider,
|
||||
SequenceableLoader.Callback<ChunkTrackStream<DashChunkSource>> {
|
||||
|
||||
/**
|
||||
@ -77,11 +80,14 @@ public final class DashSampleSource implements SampleSource,
|
||||
private final BandwidthMeter bandwidthMeter;
|
||||
private final int minLoadableRetryCount;
|
||||
private final EventDispatcher eventDispatcher;
|
||||
private final Loader loader;
|
||||
private final DataSource dataSource;
|
||||
private final MediaPresentationDescriptionParser manifestParser;
|
||||
private final ManifestCallback manifestCallback;
|
||||
|
||||
private DataSource dataSource;
|
||||
private Loader loader;
|
||||
private ChunkTrackStream<DashChunkSource>[] trackStreams;
|
||||
private CompositeSequenceableLoader sequenceableLoader;
|
||||
|
||||
private Uri manifestUri;
|
||||
private long manifestLoadStartTimestamp;
|
||||
private long manifestLoadEndTimestamp;
|
||||
@ -96,9 +102,6 @@ public final class DashSampleSource implements SampleSource,
|
||||
private TrackGroupArray trackGroups;
|
||||
private int[] trackGroupAdaptationSetIndices;
|
||||
|
||||
private ChunkTrackStream<DashChunkSource>[] trackStreams;
|
||||
private CompositeSequenceableLoader sequenceableLoader;
|
||||
|
||||
public DashSampleSource(Uri manifestUri, DataSourceFactory dataSourceFactory,
|
||||
BandwidthMeter bandwidthMeter, Handler eventHandler,
|
||||
AdaptiveSourceEventListener eventListener) {
|
||||
@ -114,18 +117,33 @@ public final class DashSampleSource implements SampleSource,
|
||||
this.bandwidthMeter = bandwidthMeter;
|
||||
this.minLoadableRetryCount = minLoadableRetryCount;
|
||||
eventDispatcher = new EventDispatcher(eventHandler, eventListener);
|
||||
dataSource = dataSourceFactory.createDataSource();
|
||||
loader = new Loader("Loader:DashSampleSource");
|
||||
manifestParser = new MediaPresentationDescriptionParser();
|
||||
manifestCallback = new ManifestCallback();
|
||||
trackStreams = newTrackStreamArray(0);
|
||||
sequenceableLoader = new CompositeSequenceableLoader(trackStreams);
|
||||
}
|
||||
|
||||
// SampleSourceProvider implementation.
|
||||
|
||||
@Override
|
||||
public int getSourceCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SampleSource createSource(int index) {
|
||||
Assertions.checkArgument(index == 0);
|
||||
return this;
|
||||
}
|
||||
|
||||
// SampleSource implementation.
|
||||
|
||||
@Override
|
||||
public void prepare(Callback callback, Allocator allocator, long positionUs) {
|
||||
this.callback = callback;
|
||||
this.allocator = allocator;
|
||||
trackStreams = newTrackStreamArray(0);
|
||||
sequenceableLoader = new CompositeSequenceableLoader(trackStreams);
|
||||
dataSource = dataSourceFactory.createDataSource();
|
||||
loader = new Loader("Loader:DashSampleSource");
|
||||
manifestRefreshHandler = new Handler();
|
||||
startLoadingManifest();
|
||||
}
|
||||
@ -212,14 +230,32 @@ public final class DashSampleSource implements SampleSource,
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
dataSource = null;
|
||||
if (loader != null) {
|
||||
loader.release();
|
||||
loader = null;
|
||||
}
|
||||
if (trackStreams != null) {
|
||||
for (ChunkTrackStream<DashChunkSource> trackStream : trackStreams) {
|
||||
trackStream.release();
|
||||
}
|
||||
trackStreams = null;
|
||||
}
|
||||
sequenceableLoader = null;
|
||||
manifestLoadStartTimestamp = 0;
|
||||
manifestLoadEndTimestamp = 0;
|
||||
manifest = null;
|
||||
callback = null;
|
||||
allocator = null;
|
||||
if (manifestRefreshHandler != null) {
|
||||
manifestRefreshHandler.removeCallbacksAndMessages(null);
|
||||
manifestRefreshHandler = null;
|
||||
}
|
||||
loader.release();
|
||||
for (ChunkTrackStream<DashChunkSource> trackStream : trackStreams) {
|
||||
trackStream.release();
|
||||
}
|
||||
prepared = false;
|
||||
durationUs = 0;
|
||||
elapsedRealtimeOffset = 0;
|
||||
trackGroups = null;
|
||||
trackGroupAdaptationSetIndices = null;
|
||||
}
|
||||
|
||||
// SequenceableLoader.Callback implementation.
|
||||
|
@ -21,6 +21,7 @@ import com.google.android.exoplayer.Format;
|
||||
import com.google.android.exoplayer.FormatHolder;
|
||||
import com.google.android.exoplayer.ParserException;
|
||||
import com.google.android.exoplayer.SampleSource;
|
||||
import com.google.android.exoplayer.SampleSourceProvider;
|
||||
import com.google.android.exoplayer.SequenceableLoader;
|
||||
import com.google.android.exoplayer.TrackGroup;
|
||||
import com.google.android.exoplayer.TrackGroupArray;
|
||||
@ -47,7 +48,8 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A {@link SampleSource} that extracts sample data using an {@link Extractor}.
|
||||
* A {@link SampleSource} that extracts sample data using an {@link Extractor}. Also acts as a
|
||||
* {@link SampleSourceProvider} providing {@link ExtractorSampleSource} instances.
|
||||
*
|
||||
* <p>If the possible input stream container formats are known, pass a factory that instantiates
|
||||
* extractors for them to the constructor. Otherwise, pass a {@link DefaultExtractorsFactory} to
|
||||
@ -57,8 +59,8 @@ import java.util.List;
|
||||
*
|
||||
* <p>Note that the built-in extractors for AAC, MPEG TS and FLV streams do not support seeking.
|
||||
*/
|
||||
public final class ExtractorSampleSource implements SampleSource, ExtractorOutput,
|
||||
Loader.Callback<ExtractorSampleSource.ExtractingLoadable>,
|
||||
public final class ExtractorSampleSource implements SampleSource, SampleSourceProvider,
|
||||
ExtractorOutput, Loader.Callback<ExtractorSampleSource.ExtractingLoadable>,
|
||||
UpstreamFormatChangedListener {
|
||||
|
||||
/**
|
||||
@ -106,13 +108,17 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
|
||||
private static final long DEFAULT_LAST_SAMPLE_DURATION_US = 10000;
|
||||
|
||||
private final Uri uri;
|
||||
private final DataSourceFactory dataSourceFactory;
|
||||
private final BandwidthMeter bandwidthMeter;
|
||||
private final ExtractorsFactory extractorsFactory;
|
||||
private final int minLoadableRetryCount;
|
||||
private final Handler eventHandler;
|
||||
private final EventListener eventListener;
|
||||
private final DataSource dataSource;
|
||||
private final ConditionVariable loadCondition;
|
||||
private final ExtractorHolder extractorHolder;
|
||||
private final Loader loader;
|
||||
|
||||
private DataSource dataSource;
|
||||
private ExtractorHolder extractorHolder;
|
||||
private Loader loader;
|
||||
private ConditionVariable loadCondition;
|
||||
|
||||
private Callback callback;
|
||||
private Allocator allocator;
|
||||
@ -166,16 +172,25 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
|
||||
BandwidthMeter bandwidthMeter, ExtractorsFactory extractorsFactory, int minLoadableRetryCount,
|
||||
Handler eventHandler, EventListener eventListener) {
|
||||
this.uri = uri;
|
||||
this.dataSourceFactory = dataSourceFactory;
|
||||
this.bandwidthMeter = bandwidthMeter;
|
||||
this.extractorsFactory = extractorsFactory;
|
||||
this.minLoadableRetryCount = minLoadableRetryCount;
|
||||
this.eventListener = eventListener;
|
||||
this.eventHandler = eventHandler;
|
||||
dataSource = dataSourceFactory.createDataSource(bandwidthMeter);
|
||||
loadCondition = new ConditionVariable();
|
||||
extractorHolder = new ExtractorHolder(extractorsFactory.createExtractors(), this);
|
||||
loader = new Loader("Loader:ExtractorSampleSource", extractorHolder);
|
||||
pendingResetPositionUs = C.UNSET_TIME_US;
|
||||
sampleQueues = new DefaultTrackOutput[0];
|
||||
length = C.LENGTH_UNBOUNDED;
|
||||
this.eventListener = eventListener;
|
||||
}
|
||||
|
||||
// SampleSourceProvider implementation.
|
||||
|
||||
@Override
|
||||
public int getSourceCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SampleSource createSource(int index) {
|
||||
Assertions.checkArgument(index == 0);
|
||||
return this;
|
||||
}
|
||||
|
||||
// SampleSource implementation.
|
||||
@ -184,6 +199,15 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
|
||||
public void prepare(Callback callback, Allocator allocator, long positionUs) {
|
||||
this.callback = callback;
|
||||
this.allocator = allocator;
|
||||
|
||||
dataSource = dataSourceFactory.createDataSource(bandwidthMeter);
|
||||
extractorHolder = new ExtractorHolder(extractorsFactory.createExtractors(), this);
|
||||
loader = new Loader("Loader:ExtractorSampleSource", extractorHolder);
|
||||
loadCondition = new ConditionVariable();
|
||||
pendingResetPositionUs = C.UNSET_TIME_US;
|
||||
sampleQueues = new DefaultTrackOutput[0];
|
||||
length = C.LENGTH_UNBOUNDED;
|
||||
|
||||
loadCondition.open();
|
||||
startLoading();
|
||||
}
|
||||
@ -318,10 +342,35 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
for (DefaultTrackOutput sampleQueue : sampleQueues) {
|
||||
sampleQueue.disable();
|
||||
dataSource = null;
|
||||
extractorHolder = null;
|
||||
if (loader != null) {
|
||||
loader.release(); // Releases extractorHolder via its own reference on the loader's thread.
|
||||
loader = null;
|
||||
}
|
||||
loader.release();
|
||||
loadCondition = null;
|
||||
callback = null;
|
||||
allocator = null;
|
||||
seekMap = null;
|
||||
tracksBuilt = false;
|
||||
prepared = false;
|
||||
seenFirstTrackSelection = false;
|
||||
notifyReset = false;
|
||||
enabledTrackCount = 0;
|
||||
if (sampleQueues != null) {
|
||||
for (DefaultTrackOutput sampleQueue : sampleQueues) {
|
||||
sampleQueue.disable();
|
||||
}
|
||||
sampleQueues = null;
|
||||
}
|
||||
tracks = null;
|
||||
durationUs = 0;
|
||||
trackEnabledStates = null;
|
||||
length = 0;
|
||||
lastSeekPositionUs = 0;
|
||||
pendingResetPositionUs = 0;
|
||||
extractedSamplesCountAtStartOfLoad = 0;
|
||||
loadingFinished = false;
|
||||
}
|
||||
|
||||
// TrackStream methods.
|
||||
|
@ -22,6 +22,7 @@ import com.google.android.exoplayer.CompositeSequenceableLoader;
|
||||
import com.google.android.exoplayer.Format;
|
||||
import com.google.android.exoplayer.ParserException;
|
||||
import com.google.android.exoplayer.SampleSource;
|
||||
import com.google.android.exoplayer.SampleSourceProvider;
|
||||
import com.google.android.exoplayer.TrackGroup;
|
||||
import com.google.android.exoplayer.TrackGroupArray;
|
||||
import com.google.android.exoplayer.TrackSelection;
|
||||
@ -38,6 +39,7 @@ import com.google.android.exoplayer.upstream.DataSource;
|
||||
import com.google.android.exoplayer.upstream.DataSourceFactory;
|
||||
import com.google.android.exoplayer.upstream.Loader;
|
||||
import com.google.android.exoplayer.upstream.ParsingLoadable;
|
||||
import com.google.android.exoplayer.util.Assertions;
|
||||
import com.google.android.exoplayer.util.MimeTypes;
|
||||
|
||||
import android.net.Uri;
|
||||
@ -51,9 +53,10 @@ import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A {@link SampleSource} for HLS streams.
|
||||
* A {@link SampleSource} for HLS streams. Also acts as a {@link SampleSourceProvider} providing
|
||||
* {@link HlsSampleSource} instances.
|
||||
*/
|
||||
public final class HlsSampleSource implements SampleSource,
|
||||
public final class HlsSampleSource implements SampleSource, SampleSourceProvider,
|
||||
Loader.Callback<ParsingLoadable<HlsPlaylist>>, HlsTrackStreamWrapper.Callback {
|
||||
|
||||
/**
|
||||
@ -68,10 +71,11 @@ public final class HlsSampleSource implements SampleSource,
|
||||
private final EventDispatcher eventDispatcher;
|
||||
private final IdentityHashMap<TrackStream, HlsTrackStreamWrapper> trackStreamSources;
|
||||
private final PtsTimestampAdjusterProvider timestampAdjusterProvider;
|
||||
private final Loader manifestFetcher;
|
||||
private final DataSource manifestDataSource;
|
||||
private final HlsPlaylistParser manifestParser;
|
||||
|
||||
private DataSource manifestDataSource;
|
||||
private Loader manifestFetcher;
|
||||
|
||||
private Callback callback;
|
||||
private Allocator allocator;
|
||||
private long preparePositionUs;
|
||||
@ -100,25 +104,38 @@ public final class HlsSampleSource implements SampleSource,
|
||||
this.dataSourceFactory = dataSourceFactory;
|
||||
this.bandwidthMeter = bandwidthMeter;
|
||||
this.minLoadableRetryCount = minLoadableRetryCount;
|
||||
|
||||
eventDispatcher = new EventDispatcher(eventHandler, eventListener);
|
||||
timestampAdjusterProvider = new PtsTimestampAdjusterProvider();
|
||||
trackStreamSources = new IdentityHashMap<>();
|
||||
|
||||
manifestDataSource = dataSourceFactory.createDataSource();
|
||||
trackStreamSources = new IdentityHashMap<>();
|
||||
timestampAdjusterProvider = new PtsTimestampAdjusterProvider();
|
||||
manifestParser = new HlsPlaylistParser();
|
||||
manifestFetcher = new Loader("Loader:ManifestFetcher");
|
||||
}
|
||||
|
||||
// SampleSourceProvider implementation.
|
||||
|
||||
@Override
|
||||
public int getSourceCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SampleSource createSource(int index) {
|
||||
Assertions.checkArgument(index == 0);
|
||||
return this;
|
||||
}
|
||||
|
||||
// SampleSource implementation.
|
||||
|
||||
@Override
|
||||
public void prepare(Callback callback, Allocator allocator, long positionUs) {
|
||||
this.callback = callback;
|
||||
this.allocator = allocator;
|
||||
this.preparePositionUs = positionUs;
|
||||
ParsingLoadable<HlsPlaylist> loadable = new ParsingLoadable<>(manifestDataSource,
|
||||
manifestUri, C.DATA_TYPE_MANIFEST, manifestParser);
|
||||
long elapsedRealtimeMs = manifestFetcher.startLoading(loadable, this,
|
||||
minLoadableRetryCount);
|
||||
preparePositionUs = positionUs;
|
||||
manifestDataSource = dataSourceFactory.createDataSource();
|
||||
manifestFetcher = new Loader("Loader:ManifestFetcher");
|
||||
ParsingLoadable<HlsPlaylist> loadable = new ParsingLoadable<>(manifestDataSource, manifestUri,
|
||||
C.DATA_TYPE_MANIFEST, manifestParser);
|
||||
long elapsedRealtimeMs = manifestFetcher.startLoading(loadable, this, minLoadableRetryCount);
|
||||
eventDispatcher.loadStarted(loadable.dataSpec, loadable.type, elapsedRealtimeMs);
|
||||
}
|
||||
|
||||
@ -212,12 +229,30 @@ public final class HlsSampleSource implements SampleSource,
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
manifestFetcher.release();
|
||||
trackStreamSources.clear();
|
||||
timestampAdjusterProvider.reset();
|
||||
manifestDataSource = null;
|
||||
if (manifestFetcher != null) {
|
||||
manifestFetcher.release();
|
||||
manifestFetcher = null;
|
||||
}
|
||||
callback = null;
|
||||
allocator = null;
|
||||
preparePositionUs = 0;
|
||||
pendingPrepareCount = 0;
|
||||
seenFirstTrackSelection = false;
|
||||
durationUs = 0;
|
||||
isLive = false;
|
||||
trackGroups = null;
|
||||
selectedTrackCounts = null;
|
||||
if (trackStreamWrappers != null) {
|
||||
for (HlsTrackStreamWrapper trackStreamWrapper : trackStreamWrappers) {
|
||||
trackStreamWrapper.release();
|
||||
}
|
||||
trackStreamWrappers = null;
|
||||
}
|
||||
enabledTrackStreamWrappers = null;
|
||||
sequenceableLoader = null;
|
||||
}
|
||||
|
||||
// Loader.Callback implementation.
|
||||
|
@ -22,6 +22,7 @@ import com.google.android.exoplayer.CompositeSequenceableLoader;
|
||||
import com.google.android.exoplayer.Format;
|
||||
import com.google.android.exoplayer.ParserException;
|
||||
import com.google.android.exoplayer.SampleSource;
|
||||
import com.google.android.exoplayer.SampleSourceProvider;
|
||||
import com.google.android.exoplayer.SequenceableLoader;
|
||||
import com.google.android.exoplayer.TrackGroup;
|
||||
import com.google.android.exoplayer.TrackGroupArray;
|
||||
@ -39,6 +40,7 @@ import com.google.android.exoplayer.upstream.DataSource;
|
||||
import com.google.android.exoplayer.upstream.DataSourceFactory;
|
||||
import com.google.android.exoplayer.upstream.Loader;
|
||||
import com.google.android.exoplayer.upstream.ParsingLoadable;
|
||||
import com.google.android.exoplayer.util.Assertions;
|
||||
import com.google.android.exoplayer.util.Util;
|
||||
|
||||
import android.net.Uri;
|
||||
@ -51,9 +53,10 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A {@link SampleSource} for SmoothStreaming media.
|
||||
* A {@link SampleSource} for SmoothStreaming media. Also acts as a {@link SampleSourceProvider}
|
||||
* providing {@link SmoothStreamingSampleSource} instances.
|
||||
*/
|
||||
public final class SmoothStreamingSampleSource implements SampleSource,
|
||||
public final class SmoothStreamingSampleSource implements SampleSource, SampleSourceProvider,
|
||||
SequenceableLoader.Callback<ChunkTrackStream<SmoothStreamingChunkSource>>,
|
||||
Loader.Callback<ParsingLoadable<SmoothStreamingManifest>> {
|
||||
|
||||
@ -70,10 +73,13 @@ public final class SmoothStreamingSampleSource implements SampleSource,
|
||||
private final BandwidthMeter bandwidthMeter;
|
||||
private final int minLoadableRetryCount;
|
||||
private final EventDispatcher eventDispatcher;
|
||||
private final Loader manifestLoader;
|
||||
private final DataSource manifestDataSource;
|
||||
private final SmoothStreamingManifestParser manifestParser;
|
||||
|
||||
private DataSource manifestDataSource;
|
||||
private Loader manifestLoader;
|
||||
private ChunkTrackStream<SmoothStreamingChunkSource>[] trackStreams;
|
||||
private CompositeSequenceableLoader sequenceableLoader;
|
||||
|
||||
private long manifestLoadStartTimestamp;
|
||||
private SmoothStreamingManifest manifest;
|
||||
|
||||
@ -86,9 +92,6 @@ public final class SmoothStreamingSampleSource implements SampleSource,
|
||||
private TrackGroupArray trackGroups;
|
||||
private int[] trackGroupElementIndices;
|
||||
|
||||
private ChunkTrackStream<SmoothStreamingChunkSource>[] trackStreams;
|
||||
private CompositeSequenceableLoader sequenceableLoader;
|
||||
|
||||
public SmoothStreamingSampleSource(Uri manifestUri, DataSourceFactory dataSourceFactory,
|
||||
BandwidthMeter bandwidthMeter, Handler eventHandler,
|
||||
AdaptiveSourceEventListener eventListener) {
|
||||
@ -105,17 +108,32 @@ public final class SmoothStreamingSampleSource implements SampleSource,
|
||||
this.bandwidthMeter = bandwidthMeter;
|
||||
this.minLoadableRetryCount = minLoadableRetryCount;
|
||||
this.eventDispatcher = new EventDispatcher(eventHandler, eventListener);
|
||||
trackStreams = newTrackStreamArray(0);
|
||||
sequenceableLoader = new CompositeSequenceableLoader(trackStreams);
|
||||
manifestDataSource = dataSourceFactory.createDataSource();
|
||||
manifestParser = new SmoothStreamingManifestParser();
|
||||
manifestLoader = new Loader("Loader:Manifest");
|
||||
}
|
||||
|
||||
// SampleSourceProvider implementation.
|
||||
|
||||
@Override
|
||||
public int getSourceCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SampleSource createSource(int index) {
|
||||
Assertions.checkArgument(index == 0);
|
||||
return this;
|
||||
}
|
||||
|
||||
// SampleSource implementation.
|
||||
|
||||
@Override
|
||||
public void prepare(Callback callback, Allocator allocator, long positionUs) {
|
||||
this.callback = callback;
|
||||
this.allocator = allocator;
|
||||
trackStreams = newTrackStreamArray(0);
|
||||
sequenceableLoader = new CompositeSequenceableLoader(trackStreams);
|
||||
manifestDataSource = dataSourceFactory.createDataSource();
|
||||
manifestLoader = new Loader("Loader:Manifest");
|
||||
manifestRefreshHandler = new Handler();
|
||||
startLoadingManifest();
|
||||
}
|
||||
@ -202,14 +220,31 @@ public final class SmoothStreamingSampleSource implements SampleSource,
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
manifestDataSource = null;
|
||||
if (manifestLoader != null) {
|
||||
manifestLoader.release();
|
||||
manifestLoader = null;
|
||||
}
|
||||
if (trackStreams != null) {
|
||||
for (ChunkTrackStream<SmoothStreamingChunkSource> trackStream : trackStreams) {
|
||||
trackStream.release();
|
||||
}
|
||||
trackStreams = null;
|
||||
}
|
||||
sequenceableLoader = null;
|
||||
manifestLoadStartTimestamp = 0;
|
||||
manifest = null;
|
||||
callback = null;
|
||||
allocator = null;
|
||||
if (manifestRefreshHandler != null) {
|
||||
manifestRefreshHandler.removeCallbacksAndMessages(null);
|
||||
manifestRefreshHandler = null;
|
||||
}
|
||||
manifestLoader.release();
|
||||
for (ChunkTrackStream<SmoothStreamingChunkSource> trackStream : trackStreams) {
|
||||
trackStream.release();
|
||||
}
|
||||
prepared = false;
|
||||
durationUs = 0;
|
||||
trackEncryptionBoxes = null;
|
||||
trackGroups = null;
|
||||
trackGroupElementIndices = null;
|
||||
}
|
||||
|
||||
// SequenceableLoader.Callback implementation
|
||||
|
@ -22,7 +22,7 @@ import com.google.android.exoplayer.ExoPlaybackException;
|
||||
import com.google.android.exoplayer.ExoPlayer;
|
||||
import com.google.android.exoplayer.MediaCodecUtil;
|
||||
import com.google.android.exoplayer.MediaCodecUtil.DecoderQueryException;
|
||||
import com.google.android.exoplayer.SampleSource;
|
||||
import com.google.android.exoplayer.SampleSourceProvider;
|
||||
import com.google.android.exoplayer.TrackGroup;
|
||||
import com.google.android.exoplayer.TrackGroupArray;
|
||||
import com.google.android.exoplayer.TrackRenderer;
|
||||
@ -44,6 +44,7 @@ import android.annotation.TargetApi;
|
||||
import android.net.Uri;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import android.util.Log;
|
||||
|
||||
import junit.framework.AssertionFailedError;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -418,7 +419,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
||||
}
|
||||
|
||||
@Override
|
||||
public SampleSource buildSource(HostActivity host, DataSourceFactory dataSourceFactory,
|
||||
public SampleSourceProvider buildSource(HostActivity host, DataSourceFactory dataSourceFactory,
|
||||
BandwidthMeter bandwidthMeter) {
|
||||
return new DashSampleSource(manifestUri, dataSourceFactory, bandwidthMeter,
|
||||
MIN_LOADABLE_RETRY_COUNT, null, null);
|
||||
|
@ -22,7 +22,7 @@ import com.google.android.exoplayer.ExoPlaybackException;
|
||||
import com.google.android.exoplayer.ExoPlayer;
|
||||
import com.google.android.exoplayer.ExoPlayerFactory;
|
||||
import com.google.android.exoplayer.Format;
|
||||
import com.google.android.exoplayer.SampleSource;
|
||||
import com.google.android.exoplayer.SampleSourceProvider;
|
||||
import com.google.android.exoplayer.SimpleExoPlayer;
|
||||
import com.google.android.exoplayer.TrackSelectionPolicy;
|
||||
import com.google.android.exoplayer.audio.AudioTrack;
|
||||
@ -129,7 +129,7 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
|
||||
player = buildExoPlayer(host, surface, trackSelector);
|
||||
DataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(host, Util
|
||||
.getUserAgent(host, "ExoPlayerPlaybackTests"));
|
||||
player.setSource(buildSource(host, dataSourceFactory, player.getBandwidthMeter()));
|
||||
player.setSourceProvider(buildSource(host, dataSourceFactory, player.getBandwidthMeter()));
|
||||
player.addListener(this);
|
||||
player.setDebugListener(this);
|
||||
player.setPlayWhenReady(true);
|
||||
@ -288,7 +288,7 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
protected abstract SampleSource buildSource(HostActivity host,
|
||||
protected abstract SampleSourceProvider buildSource(HostActivity host,
|
||||
DataSourceFactory dataSourceFactory, BandwidthMeter bandwidthMeter);
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
|
Loading…
x
Reference in New Issue
Block a user