Make ExtractorSampleSource amenable to proguarding.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=122085277
This commit is contained in:
olly 2016-05-11 13:12:41 -07:00 committed by Oliver Woodman
parent 356288a018
commit f9f95d638b
5 changed files with 137 additions and 115 deletions

View File

@ -283,8 +283,8 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
case Util.TYPE_OTHER:
Allocator allocator = new DefaultAllocator(C.DEFAULT_BUFFER_SEGMENT_SIZE);
DataSource dataSource = dataSourceFactory.createDataSource(player.getBandwidthMeter());
return new ExtractorSampleSource(uri, dataSource, allocator,
C.DEFAULT_MUXED_BUFFER_SIZE, player.getMainHandler(), player, 0);
return new ExtractorSampleSource(uri, dataSource, allocator, C.DEFAULT_MUXED_BUFFER_SIZE,
player.getMainHandler(), player, 0, ExtractorSampleSource.newDefaultExtractors());
default:
throw new IllegalStateException("Unsupported type: " + type);
}

View File

@ -19,6 +19,7 @@ import com.google.android.exoplayer.DefaultTrackSelector;
import com.google.android.exoplayer.ExoPlaybackException;
import com.google.android.exoplayer.ExoPlayer;
import com.google.android.exoplayer.TrackRenderer;
import com.google.android.exoplayer.extractor.Extractor;
import com.google.android.exoplayer.extractor.ExtractorSampleSource;
import com.google.android.exoplayer.extractor.mkv.MatroskaExtractor;
import com.google.android.exoplayer.upstream.DefaultAllocator;
@ -83,7 +84,7 @@ public class FlacPlaybackTest extends InstrumentationTestCase {
new DefaultDataSource(context, null, Util.getUserAgent(context, "ExoPlayerExtFlacTest"),
false),
new DefaultAllocator(BUFFER_SEGMENT_SIZE), BUFFER_SEGMENT_SIZE * BUFFER_SEGMENT_COUNT,
new MatroskaExtractor());
new Extractor[] {new MatroskaExtractor()});
player.setSource(sampleSource);
player.setPlayWhenReady(true);
Looper.loop();

View File

@ -19,6 +19,7 @@ import com.google.android.exoplayer.DefaultTrackSelector;
import com.google.android.exoplayer.ExoPlaybackException;
import com.google.android.exoplayer.ExoPlayer;
import com.google.android.exoplayer.TrackRenderer;
import com.google.android.exoplayer.extractor.Extractor;
import com.google.android.exoplayer.extractor.ExtractorSampleSource;
import com.google.android.exoplayer.extractor.mkv.MatroskaExtractor;
import com.google.android.exoplayer.upstream.DefaultAllocator;
@ -83,7 +84,7 @@ public class OpusPlaybackTest extends InstrumentationTestCase {
new DefaultDataSource(context, null, Util.getUserAgent(context, "ExoPlayerExtOpusTest"),
false),
new DefaultAllocator(BUFFER_SEGMENT_SIZE), BUFFER_SEGMENT_SIZE * BUFFER_SEGMENT_COUNT,
new MatroskaExtractor());
new Extractor[] {new MatroskaExtractor()});
player.setSource(sampleSource);
player.setPlayWhenReady(true);
Looper.loop();

View File

@ -19,6 +19,7 @@ import com.google.android.exoplayer.DefaultTrackSelector;
import com.google.android.exoplayer.ExoPlaybackException;
import com.google.android.exoplayer.ExoPlayer;
import com.google.android.exoplayer.TrackRenderer;
import com.google.android.exoplayer.extractor.Extractor;
import com.google.android.exoplayer.extractor.ExtractorSampleSource;
import com.google.android.exoplayer.extractor.mkv.MatroskaExtractor;
import com.google.android.exoplayer.upstream.DefaultAllocator;
@ -99,7 +100,7 @@ public class VpxPlaybackTest extends InstrumentationTestCase {
new DefaultDataSource(context, null, Util.getUserAgent(context, "ExoPlayerExtVP9Test"),
false),
new DefaultAllocator(BUFFER_SEGMENT_SIZE), BUFFER_SEGMENT_SIZE * BUFFER_SEGMENT_COUNT,
new MatroskaExtractor());
new Extractor[] {new MatroskaExtractor()});
player.sendMessage(videoRenderer, LibvpxVideoTrackRenderer.MSG_SET_OUTPUT_BUFFER_RENDERER,
new VpxVideoSurfaceView(context));
player.setSource(sampleSource);

View File

@ -108,94 +108,8 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
private static final int MIN_RETRY_COUNT_DEFAULT_FOR_MEDIA = -1;
/**
* Default extractor classes in priority order. They are referred to indirectly so that it is
* possible to remove unused extractors.
*/
private static final List<Class<? extends Extractor>> DEFAULT_EXTRACTOR_CLASSES;
static {
DEFAULT_EXTRACTOR_CLASSES = new ArrayList<>();
// Load extractors using reflection so that they can be deleted cleanly.
// Class.forName(<class name>) appears for each extractor so that automated tools like proguard
// can detect the use of reflection (see http://proguard.sourceforge.net/FAQ.html#forname).
try {
DEFAULT_EXTRACTOR_CLASSES.add(
Class.forName("com.google.android.exoplayer.extractor.mkv.MatroskaExtractor")
.asSubclass(Extractor.class));
} catch (ClassNotFoundException e) {
// Extractor not found.
}
try {
DEFAULT_EXTRACTOR_CLASSES.add(
Class.forName("com.google.android.exoplayer.extractor.mp4.FragmentedMp4Extractor")
.asSubclass(Extractor.class));
} catch (ClassNotFoundException e) {
// Extractor not found.
}
try {
DEFAULT_EXTRACTOR_CLASSES.add(
Class.forName("com.google.android.exoplayer.extractor.mp4.Mp4Extractor")
.asSubclass(Extractor.class));
} catch (ClassNotFoundException e) {
// Extractor not found.
}
try {
DEFAULT_EXTRACTOR_CLASSES.add(
Class.forName("com.google.android.exoplayer.extractor.mp3.Mp3Extractor")
.asSubclass(Extractor.class));
} catch (ClassNotFoundException e) {
// Extractor not found.
}
try {
DEFAULT_EXTRACTOR_CLASSES.add(
Class.forName("com.google.android.exoplayer.extractor.ts.AdtsExtractor")
.asSubclass(Extractor.class));
} catch (ClassNotFoundException e) {
// Extractor not found.
}
try {
DEFAULT_EXTRACTOR_CLASSES.add(
Class.forName("com.google.android.exoplayer.extractor.ts.TsExtractor")
.asSubclass(Extractor.class));
} catch (ClassNotFoundException e) {
// Extractor not found.
}
try {
DEFAULT_EXTRACTOR_CLASSES.add(
Class.forName("com.google.android.exoplayer.extractor.flv.FlvExtractor")
.asSubclass(Extractor.class));
} catch (ClassNotFoundException e) {
// Extractor not found.
}
try {
DEFAULT_EXTRACTOR_CLASSES.add(
Class.forName("com.google.android.exoplayer.extractor.ogg.OggExtractor")
.asSubclass(Extractor.class));
} catch (ClassNotFoundException e) {
// Extractor not found.
}
try {
DEFAULT_EXTRACTOR_CLASSES.add(
Class.forName("com.google.android.exoplayer.extractor.ts.PsExtractor")
.asSubclass(Extractor.class));
} catch (ClassNotFoundException e) {
// Extractor not found.
}
try {
DEFAULT_EXTRACTOR_CLASSES.add(
Class.forName("com.google.android.exoplayer.extractor.wav.WavExtractor")
.asSubclass(Extractor.class));
} catch (ClassNotFoundException e) {
// Extractor not found.
}
try {
DEFAULT_EXTRACTOR_CLASSES.add(
Class.forName("com.google.android.exoplayer.ext.flac.FlacExtractor")
.asSubclass(Extractor.class));
} catch (ClassNotFoundException e) {
// Extractor not found.
}
}
// Lazily initialized default extractor classes in priority order.
private static List<Class<? extends Extractor>> defaultExtractorClasses;
private final Loader loader;
private final ExtractorHolder extractorHolder;
@ -235,11 +149,13 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
* @param allocator An {@link Allocator} from which to obtain memory allocations.
* @param requestedBufferSize The requested total buffer size for storing sample data, in bytes.
* The actual allocated size may exceed the value passed in if the implementation requires it.
* @param extractors {@link Extractor}s to extract the media stream, in order of decreasing
* priority. If omitted, the default extractors will be used.
* @param extractors {@link Extractor}s to process the media stream. Where the possible formats
* are known, instantiate and inject only instances of the corresponding {@link Extractor}s.
* Where this is not possible, {@link #newDefaultExtractors()} can be used to construct an
* array of default extractors.
*/
public ExtractorSampleSource(Uri uri, DataSource dataSource, Allocator allocator,
int requestedBufferSize, Extractor... extractors) {
int requestedBufferSize, Extractor[] extractors) {
this(uri, dataSource, allocator, requestedBufferSize, MIN_RETRY_COUNT_DEFAULT_FOR_MEDIA,
extractors);
}
@ -254,12 +170,14 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
* null if delivery of events is not required.
* @param eventListener A listener of events. May be null if delivery of events is not required.
* @param eventSourceId An identifier that gets passed to {@code eventListener} methods.
* @param extractors {@link Extractor}s to extract the media stream, in order of decreasing
* priority. If omitted, the default extractors will be used.
* @param extractors {@link Extractor}s to process the media stream. Where the possible formats
* are known, instantiate and inject only instances of the corresponding {@link Extractor}s.
* Where this is not possible, {@link #newDefaultExtractors()} can be used to construct an
* array of default extractors.
*/
public ExtractorSampleSource(Uri uri, DataSource dataSource, Allocator allocator,
int requestedBufferSize, Handler eventHandler, EventListener eventListener,
int eventSourceId, Extractor... extractors) {
int eventSourceId, Extractor[] extractors) {
this(uri, dataSource, allocator, requestedBufferSize, MIN_RETRY_COUNT_DEFAULT_FOR_MEDIA,
eventHandler, eventListener, eventSourceId, extractors);
}
@ -272,11 +190,13 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
* The actual allocated size may exceed the value passed in if the implementation requires it.
* @param minLoadableRetryCount The minimum number of times that the sample source will retry
* if a loading error occurs.
* @param extractors {@link Extractor}s to extract the media stream, in order of decreasing
* priority. If omitted, the default extractors will be used.
* @param extractors {@link Extractor}s to process the media stream. Where the possible formats
* are known, instantiate and inject only instances of the corresponding {@link Extractor}s.
* Where this is not possible, {@link #newDefaultExtractors()} can be used to construct an
* array of default extractors.
*/
public ExtractorSampleSource(Uri uri, DataSource dataSource, Allocator allocator,
int requestedBufferSize, int minLoadableRetryCount, Extractor... extractors) {
int requestedBufferSize, int minLoadableRetryCount, Extractor[] extractors) {
this(uri, dataSource, allocator, requestedBufferSize, minLoadableRetryCount, null, null, 0,
extractors);
}
@ -293,12 +213,15 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
* null if delivery of events is not required.
* @param eventListener A listener of events. May be null if delivery of events is not required.
* @param eventSourceId An identifier that gets passed to {@code eventListener} methods.
* @param extractors {@link Extractor}s to extract the media stream, in order of decreasing
* priority. If omitted, the default extractors will be used.
* @param extractors {@link Extractor}s to process the media stream. Where the possible formats
* are known, instantiate and inject only instances of the corresponding {@link Extractor}s.
* Where this is not possible {@link #newDefaultExtractors()} can be used to construct an
* array of default extractors.
*/
public ExtractorSampleSource(Uri uri, DataSource dataSource, Allocator allocator,
int requestedBufferSize, int minLoadableRetryCount, Handler eventHandler,
EventListener eventListener, int eventSourceId, Extractor... extractors) {
EventListener eventListener, int eventSourceId, Extractor[] extractors) {
Assertions.checkState(extractors != null && extractors.length > 0);
this.uri = uri;
this.dataSource = dataSource;
this.eventListener = eventListener;
@ -311,21 +234,117 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
int initialMinRetryCount = minLoadableRetryCount == MIN_RETRY_COUNT_DEFAULT_FOR_MEDIA
? DEFAULT_MIN_LOADABLE_RETRY_COUNT_ON_DEMAND : minLoadableRetryCount;
loader = new Loader("Loader:ExtractorSampleSource", initialMinRetryCount);
if (extractors == null || extractors.length == 0) {
extractors = new Extractor[DEFAULT_EXTRACTOR_CLASSES.size()];
for (int i = 0; i < extractors.length; i++) {
try {
extractors[i] = DEFAULT_EXTRACTOR_CLASSES.get(i).newInstance();
} catch (Exception e) {
throw new IllegalStateException("Unexpected error creating default extractor", e);
}
}
}
extractorHolder = new ExtractorHolder(extractors, this);
pendingResetPositionUs = C.UNSET_TIME_US;
sampleQueues = new DefaultTrackOutput[0];
}
/**
* Builds default extractors that can be passed to an {@link ExtractorSampleSource} constructor.
*
* @return An array of default extractors.
*/
public static Extractor[] newDefaultExtractors() {
synchronized (ExtractorSampleSource.class) {
if (defaultExtractorClasses == null) {
// Lazily initialize defaultExtractorClasses.
List<Class<? extends Extractor>> extractorClasses = new ArrayList<>();
// We reference extractors using reflection so that they can be deleted cleanly.
// Class.forName is used so that automated tools like proguard can detect the use of
// reflection (see http://proguard.sourceforge.net/FAQ.html#forname).
try {
extractorClasses.add(
Class.forName("com.google.android.exoplayer.extractor.mkv.MatroskaExtractor")
.asSubclass(Extractor.class));
} catch (ClassNotFoundException e) {
// Extractor not found.
}
try {
extractorClasses.add(
Class.forName("com.google.android.exoplayer.extractor.mp4.FragmentedMp4Extractor")
.asSubclass(Extractor.class));
} catch (ClassNotFoundException e) {
// Extractor not found.
}
try {
extractorClasses.add(
Class.forName("com.google.android.exoplayer.extractor.mp4.Mp4Extractor")
.asSubclass(Extractor.class));
} catch (ClassNotFoundException e) {
// Extractor not found.
}
try {
extractorClasses.add(
Class.forName("com.google.android.exoplayer.extractor.mp3.Mp3Extractor")
.asSubclass(Extractor.class));
} catch (ClassNotFoundException e) {
// Extractor not found.
}
try {
extractorClasses.add(
Class.forName("com.google.android.exoplayer.extractor.ts.AdtsExtractor")
.asSubclass(Extractor.class));
} catch (ClassNotFoundException e) {
// Extractor not found.
}
try {
extractorClasses.add(
Class.forName("com.google.android.exoplayer.extractor.ts.TsExtractor")
.asSubclass(Extractor.class));
} catch (ClassNotFoundException e) {
// Extractor not found.
}
try {
extractorClasses.add(
Class.forName("com.google.android.exoplayer.extractor.flv.FlvExtractor")
.asSubclass(Extractor.class));
} catch (ClassNotFoundException e) {
// Extractor not found.
}
try {
extractorClasses.add(
Class.forName("com.google.android.exoplayer.extractor.ogg.OggExtractor")
.asSubclass(Extractor.class));
} catch (ClassNotFoundException e) {
// Extractor not found.
}
try {
extractorClasses.add(
Class.forName("com.google.android.exoplayer.extractor.ts.PsExtractor")
.asSubclass(Extractor.class));
} catch (ClassNotFoundException e) {
// Extractor not found.
}
try {
extractorClasses.add(
Class.forName("com.google.android.exoplayer.extractor.wav.WavExtractor")
.asSubclass(Extractor.class));
} catch (ClassNotFoundException e) {
// Extractor not found.
}
try {
extractorClasses.add(
Class.forName("com.google.android.exoplayer.ext.flac.FlacExtractor")
.asSubclass(Extractor.class));
} catch (ClassNotFoundException e) {
// Extractor not found.
}
defaultExtractorClasses = extractorClasses;
}
}
Extractor[] extractors = new Extractor[defaultExtractorClasses.size()];
for (int i = 0; i < extractors.length; i++) {
try {
extractors[i] = defaultExtractorClasses.get(i).newInstance();
} catch (Exception e) {
// Should never happen.
throw new IllegalStateException("Unexpected error creating default extractor", e);
}
}
return extractors;
}
// SampleSource implementation.
@Override