Commit dd031691 by andrewlewis Committed by Oliver Woodman

Pass an ExtractorsFactory to ExtractorSampleSource.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=126672854
parent 06fd826a
Showing with 356 additions and 158 deletions
...@@ -18,6 +18,7 @@ package com.google.android.exoplayer.demo; ...@@ -18,6 +18,7 @@ package com.google.android.exoplayer.demo;
import com.google.android.exoplayer.SampleSource; import com.google.android.exoplayer.SampleSource;
import com.google.android.exoplayer.SampleSourceProvider; import com.google.android.exoplayer.SampleSourceProvider;
import com.google.android.exoplayer.dash.DashSampleSource; 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.extractor.ExtractorSampleSource;
import com.google.android.exoplayer.hls.HlsSampleSource; import com.google.android.exoplayer.hls.HlsSampleSource;
import com.google.android.exoplayer.smoothstreaming.SmoothStreamingSampleSource; import com.google.android.exoplayer.smoothstreaming.SmoothStreamingSampleSource;
...@@ -81,7 +82,7 @@ public final class UriSampleSourceProvider implements SampleSourceProvider { ...@@ -81,7 +82,7 @@ public final class UriSampleSourceProvider implements SampleSourceProvider {
return new HlsSampleSource(uri, dataSourceFactory, bandwidthMeter, handler, eventLogger); return new HlsSampleSource(uri, dataSourceFactory, bandwidthMeter, handler, eventLogger);
case Util.TYPE_OTHER: case Util.TYPE_OTHER:
return new ExtractorSampleSource(uri, dataSourceFactory, bandwidthMeter, return new ExtractorSampleSource(uri, dataSourceFactory, bandwidthMeter,
ExtractorSampleSource.newDefaultExtractors(), handler, eventLogger); new DefaultExtractorsFactory(), handler, eventLogger);
default: default:
throw new IllegalStateException("Unsupported type: " + type); throw new IllegalStateException("Unsupported type: " + type);
} }
......
...@@ -21,7 +21,6 @@ import com.google.android.exoplayer.ExoPlaybackException; ...@@ -21,7 +21,6 @@ import com.google.android.exoplayer.ExoPlaybackException;
import com.google.android.exoplayer.ExoPlayer; import com.google.android.exoplayer.ExoPlayer;
import com.google.android.exoplayer.ExoPlayerFactory; import com.google.android.exoplayer.ExoPlayerFactory;
import com.google.android.exoplayer.TrackRenderer; 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.ExtractorSampleSource;
import com.google.android.exoplayer.extractor.mkv.MatroskaExtractor; import com.google.android.exoplayer.extractor.mkv.MatroskaExtractor;
import com.google.android.exoplayer.upstream.DefaultDataSourceFactory; import com.google.android.exoplayer.upstream.DefaultDataSourceFactory;
...@@ -79,9 +78,11 @@ public class FlacPlaybackTest extends InstrumentationTestCase { ...@@ -79,9 +78,11 @@ public class FlacPlaybackTest extends InstrumentationTestCase {
player.addListener(this); player.addListener(this);
ExtractorSampleSource sampleSource = new ExtractorSampleSource( ExtractorSampleSource sampleSource = new ExtractorSampleSource(
uri, uri,
new DefaultDataSourceFactory(context, "ExoPlayerExtFlacTest"), null, new DefaultDataSourceFactory(context, "ExoPlayerExtFlacTest"),
new Extractor[] {new MatroskaExtractor()}, null,
null, null); new MatroskaExtractor.Factory(),
null,
null);
player.setSource(sampleSource); player.setSource(sampleSource);
player.setPlayWhenReady(true); player.setPlayWhenReady(true);
Looper.loop(); Looper.loop();
......
...@@ -20,6 +20,7 @@ import com.google.android.exoplayer.Format; ...@@ -20,6 +20,7 @@ import com.google.android.exoplayer.Format;
import com.google.android.exoplayer.extractor.Extractor; import com.google.android.exoplayer.extractor.Extractor;
import com.google.android.exoplayer.extractor.ExtractorInput; import com.google.android.exoplayer.extractor.ExtractorInput;
import com.google.android.exoplayer.extractor.ExtractorOutput; import com.google.android.exoplayer.extractor.ExtractorOutput;
import com.google.android.exoplayer.extractor.ExtractorsFactory;
import com.google.android.exoplayer.extractor.PositionHolder; import com.google.android.exoplayer.extractor.PositionHolder;
import com.google.android.exoplayer.extractor.SeekMap; import com.google.android.exoplayer.extractor.SeekMap;
import com.google.android.exoplayer.extractor.TrackOutput; import com.google.android.exoplayer.extractor.TrackOutput;
...@@ -37,6 +38,18 @@ import java.util.Arrays; ...@@ -37,6 +38,18 @@ import java.util.Arrays;
public final class FlacExtractor implements Extractor { public final class FlacExtractor implements Extractor {
/** /**
* Factory that returns one extractor which is a {@link FlacExtractor}.
*/
public static final class Factory implements ExtractorsFactory {
@Override
public Extractor[] createExtractors() {
return new Extractor[] {new FlacExtractor()};
}
}
/**
* FLAC signature: first 4 is the signature word, second 4 is the sizeof STREAMINFO. 0x22 is the * FLAC signature: first 4 is the signature word, second 4 is the sizeof STREAMINFO. 0x22 is the
* mandatory STREAMINFO. * mandatory STREAMINFO.
*/ */
......
...@@ -21,7 +21,6 @@ import com.google.android.exoplayer.ExoPlaybackException; ...@@ -21,7 +21,6 @@ import com.google.android.exoplayer.ExoPlaybackException;
import com.google.android.exoplayer.ExoPlayer; import com.google.android.exoplayer.ExoPlayer;
import com.google.android.exoplayer.ExoPlayerFactory; import com.google.android.exoplayer.ExoPlayerFactory;
import com.google.android.exoplayer.TrackRenderer; 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.ExtractorSampleSource;
import com.google.android.exoplayer.extractor.mkv.MatroskaExtractor; import com.google.android.exoplayer.extractor.mkv.MatroskaExtractor;
import com.google.android.exoplayer.upstream.DefaultDataSourceFactory; import com.google.android.exoplayer.upstream.DefaultDataSourceFactory;
...@@ -79,9 +78,11 @@ public class OpusPlaybackTest extends InstrumentationTestCase { ...@@ -79,9 +78,11 @@ public class OpusPlaybackTest extends InstrumentationTestCase {
player.addListener(this); player.addListener(this);
ExtractorSampleSource sampleSource = new ExtractorSampleSource( ExtractorSampleSource sampleSource = new ExtractorSampleSource(
uri, uri,
new DefaultDataSourceFactory(context, "ExoPlayerExtOpusTest"), null, new DefaultDataSourceFactory(context, "ExoPlayerExtOpusTest"),
new Extractor[] {new MatroskaExtractor()}, null,
null, null); new MatroskaExtractor.Factory(),
null,
null);
player.setSource(sampleSource); player.setSource(sampleSource);
player.setPlayWhenReady(true); player.setPlayWhenReady(true);
Looper.loop(); Looper.loop();
......
...@@ -21,7 +21,6 @@ import com.google.android.exoplayer.ExoPlaybackException; ...@@ -21,7 +21,6 @@ import com.google.android.exoplayer.ExoPlaybackException;
import com.google.android.exoplayer.ExoPlayer; import com.google.android.exoplayer.ExoPlayer;
import com.google.android.exoplayer.ExoPlayerFactory; import com.google.android.exoplayer.ExoPlayerFactory;
import com.google.android.exoplayer.TrackRenderer; 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.ExtractorSampleSource;
import com.google.android.exoplayer.extractor.mkv.MatroskaExtractor; import com.google.android.exoplayer.extractor.mkv.MatroskaExtractor;
import com.google.android.exoplayer.upstream.DefaultDataSourceFactory; import com.google.android.exoplayer.upstream.DefaultDataSourceFactory;
...@@ -95,9 +94,11 @@ public class VpxPlaybackTest extends InstrumentationTestCase { ...@@ -95,9 +94,11 @@ public class VpxPlaybackTest extends InstrumentationTestCase {
player.addListener(this); player.addListener(this);
ExtractorSampleSource sampleSource = new ExtractorSampleSource( ExtractorSampleSource sampleSource = new ExtractorSampleSource(
uri, uri,
new DefaultDataSourceFactory(context, "ExoPlayerExtVp9Test"), null, new DefaultDataSourceFactory(context, "ExoPlayerExtVp9Test"),
new Extractor[] {new MatroskaExtractor()}, null,
null, null); new MatroskaExtractor.Factory(),
null,
null);
player.sendMessages(new ExoPlayer.ExoPlayerMessage(videoRenderer, player.sendMessages(new ExoPlayer.ExoPlayerMessage(videoRenderer,
LibvpxVideoTrackRenderer.MSG_SET_OUTPUT_BUFFER_RENDERER, LibvpxVideoTrackRenderer.MSG_SET_OUTPUT_BUFFER_RENDERER,
new VpxVideoSurfaceView(context))); new VpxVideoSurfaceView(context)));
......
/*
* 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.extractor;
import java.util.ArrayList;
import java.util.List;
/**
* An {@link ExtractorsFactory} that provides an array of extractors for the following formats:
*
* <ul>
* <li>MP4, including M4A ({@link com.google.android.exoplayer.extractor.mp4.Mp4Extractor})</li>
* <li>fMP4 ({@link com.google.android.exoplayer.extractor.mp4.FragmentedMp4Extractor})</li>
* <li>Matroska and WebM ({@link com.google.android.exoplayer.extractor.mkv.MatroskaExtractor})
* </li>
* <li>Ogg Vorbis/FLAC ({@link com.google.android.exoplayer.extractor.ogg.OggExtractor}</li>
* <li>MP3 ({@link com.google.android.exoplayer.extractor.mp3.Mp3Extractor})</li>
* <li>AAC ({@link com.google.android.exoplayer.extractor.ts.AdtsExtractor})</li>
* <li>MPEG TS ({@link com.google.android.exoplayer.extractor.ts.TsExtractor})</li>
* <li>MPEG PS ({@link com.google.android.exoplayer.extractor.ts.PsExtractor})</li>
* <li>FLV ({@link com.google.android.exoplayer.extractor.flv.FlvExtractor})</li>
* <li>WAV ({@link com.google.android.exoplayer.extractor.wav.WavExtractor})</li>
* <li>FLAC (only available if the FLAC extension is built and included)</li>
* </ul>
*/
public final class DefaultExtractorsFactory implements ExtractorsFactory {
// Lazily initialized default extractor classes in priority order.
private static List<Class<? extends Extractor>> defaultExtractorClasses;
/**
* Creates a new factory for the default extractors.
*/
public DefaultExtractorsFactory() {
synchronized (DefaultExtractorsFactory.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;
}
}
}
@Override
public Extractor[] createExtractors() {
Extractor[] extractors = new Extractor[defaultExtractorClasses.size()];
for (int i = 0; i < extractors.length; i++) {
try {
extractors[i] = defaultExtractorClasses.get(i).getConstructor().newInstance();
} catch (Exception e) {
// Should never happen.
throw new IllegalStateException("Unexpected error creating default extractor", e);
}
}
return extractors;
}
}
...@@ -43,35 +43,19 @@ import android.os.Handler; ...@@ -43,35 +43,19 @@ import android.os.Handler;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; 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}.
* *
* <p>If no {@link Extractor} instances are passed to the constructor, the input stream container * <p>If the possible input stream container formats are known, pass a factory that instantiates
* format will be detected automatically from the following supported formats: * extractors for them to the constructor. Otherwise, pass a {@link DefaultExtractorsFactory} to
* use the default extractors. When reading a new stream, the first {@link Extractor} in the array
* of extractors created by the factory that returns {@code true} from
* {@link Extractor#sniff(ExtractorInput)} will be used to extract samples from the input stream.
* *
* <ul> * <p>Note that the built-in extractors for AAC, MPEG TS and FLV streams do not support seeking.
* <li>MP4, including M4A ({@link com.google.android.exoplayer.extractor.mp4.Mp4Extractor})</li>
* <li>fMP4 ({@link com.google.android.exoplayer.extractor.mp4.FragmentedMp4Extractor})</li>
* <li>Matroska and WebM ({@link com.google.android.exoplayer.extractor.mkv.MatroskaExtractor})</li>
* <li>Ogg Vorbis/FLAC ({@link com.google.android.exoplayer.extractor.ogg.OggExtractor}</li>
* <li>MP3 ({@link com.google.android.exoplayer.extractor.mp3.Mp3Extractor})</li>
* <li>AAC ({@link com.google.android.exoplayer.extractor.ts.AdtsExtractor})</li>
* <li>MPEG TS ({@link com.google.android.exoplayer.extractor.ts.TsExtractor})</li>
* <li>MPEG PS ({@link com.google.android.exoplayer.extractor.ts.PsExtractor})</li>
* <li>FLV ({@link com.google.android.exoplayer.extractor.flv.FlvExtractor})</li>
* <li>WAV ({@link com.google.android.exoplayer.extractor.wav.WavExtractor})</li>
* <li>FLAC (only available if the FLAC extension is built and included)</li>
* </ul>
*
* <p>Seeking in AAC, MPEG TS and FLV streams is not supported.
*
* <p>To override the default extractors, pass one or more {@link Extractor} instances to the
* constructor. When reading a new stream, the first {@link Extractor} that returns {@code true}
* from {@link Extractor#sniff(ExtractorInput)} will be used.
*/ */
public final class ExtractorSampleSource implements SampleSource, ExtractorOutput, public final class ExtractorSampleSource implements SampleSource, ExtractorOutput,
Loader.Callback<ExtractorSampleSource.ExtractingLoadable>, Loader.Callback<ExtractorSampleSource.ExtractingLoadable>,
...@@ -121,9 +105,6 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu ...@@ -121,9 +105,6 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
*/ */
private static final long DEFAULT_LAST_SAMPLE_DURATION_US = 10000; private static final long DEFAULT_LAST_SAMPLE_DURATION_US = 10000;
// Lazily initialized default extractor classes in priority order.
private static List<Class<? extends Extractor>> defaultExtractorClasses;
private final Uri uri; private final Uri uri;
private final int minLoadableRetryCount; private final int minLoadableRetryCount;
private final Handler eventHandler; private final Handler eventHandler;
...@@ -158,35 +139,32 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu ...@@ -158,35 +139,32 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
* @param uri The {@link Uri} of the media stream. * @param uri The {@link Uri} of the media stream.
* @param dataSourceFactory A factory for {@link DataSource}s to read the media. * @param dataSourceFactory A factory for {@link DataSource}s to read the media.
* @param bandwidthMeter A {@link BandwidthMeter} to notify of loads performed by the source. * @param bandwidthMeter A {@link BandwidthMeter} to notify of loads performed by the source.
* @param extractors {@link Extractor}s to process the media stream. Where the possible formats * @param extractorsFactory Factory for {@link Extractor}s to process the media stream. If the
* are known, instantiate and inject only instances of the corresponding {@link Extractor}s. * possible formats are known, pass a factory that instantiates extractors for those formats.
* Where this is not possible, {@link #newDefaultExtractors()} can be used to construct an * Otherwise, pass a {@link DefaultExtractorsFactory} to use default extractors.
* array of default extractors.
* @param eventListener A listener of events. May be null if delivery of events is not required. * @param eventListener A listener of events. May be null if delivery of events is not required.
*/ */
public ExtractorSampleSource(Uri uri, DataSourceFactory dataSourceFactory, public ExtractorSampleSource(Uri uri, DataSourceFactory dataSourceFactory,
BandwidthMeter bandwidthMeter, Extractor[] extractors, Handler eventHandler, BandwidthMeter bandwidthMeter, ExtractorsFactory extractorsFactory, Handler eventHandler,
EventListener eventListener) { EventListener eventListener) {
this(uri, dataSourceFactory, bandwidthMeter, extractors, MIN_RETRY_COUNT_DEFAULT_FOR_MEDIA, this(uri, dataSourceFactory, bandwidthMeter, extractorsFactory,
eventHandler, eventListener); MIN_RETRY_COUNT_DEFAULT_FOR_MEDIA, eventHandler, eventListener);
} }
/** /**
* @param uri The {@link Uri} of the media stream. * @param uri The {@link Uri} of the media stream.
* @param dataSourceFactory A factory for {@link DataSource}s to read the media. * @param dataSourceFactory A factory for {@link DataSource}s to read the media.
* @param bandwidthMeter A {@link BandwidthMeter} to notify of loads performed by the source. * @param bandwidthMeter A {@link BandwidthMeter} to notify of loads performed by the source.
* @param extractors {@link Extractor}s to process the media stream. Where the possible formats * @param extractorsFactory Factory for {@link Extractor}s to process the media stream. If the
* are known, instantiate and inject only instances of the corresponding {@link Extractor}s. * possible formats are known, pass a factory that instantiates extractors for those formats.
* Where this is not possible, {@link #newDefaultExtractors()} can be used to construct an * Otherwise, pass a {@link DefaultExtractorsFactory} to use default extractors.
* array of default extractors.
* @param minLoadableRetryCount The minimum number of times that the sample source will retry * @param minLoadableRetryCount The minimum number of times that the sample source will retry
* if a loading error occurs. * if a loading error occurs.
* @param eventListener A listener of events. May be null if delivery of events is not required. * @param eventListener A listener of events. May be null if delivery of events is not required.
*/ */
public ExtractorSampleSource(Uri uri, DataSourceFactory dataSourceFactory, public ExtractorSampleSource(Uri uri, DataSourceFactory dataSourceFactory,
BandwidthMeter bandwidthMeter, Extractor[] extractors, int minLoadableRetryCount, BandwidthMeter bandwidthMeter, ExtractorsFactory extractorsFactory, int minLoadableRetryCount,
Handler eventHandler, EventListener eventListener) { Handler eventHandler, EventListener eventListener) {
Assertions.checkState(extractors != null && extractors.length > 0);
this.uri = uri; this.uri = uri;
this.minLoadableRetryCount = minLoadableRetryCount; this.minLoadableRetryCount = minLoadableRetryCount;
this.eventListener = eventListener; this.eventListener = eventListener;
...@@ -194,118 +172,12 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu ...@@ -194,118 +172,12 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
dataSource = dataSourceFactory.createDataSource(bandwidthMeter); dataSource = dataSourceFactory.createDataSource(bandwidthMeter);
loadCondition = new ConditionVariable(); loadCondition = new ConditionVariable();
loader = new Loader("Loader:ExtractorSampleSource"); loader = new Loader("Loader:ExtractorSampleSource");
extractorHolder = new ExtractorHolder(extractors, this); extractorHolder = new ExtractorHolder(extractorsFactory.createExtractors(), this);
pendingResetPositionUs = C.UNSET_TIME_US; pendingResetPositionUs = C.UNSET_TIME_US;
sampleQueues = new DefaultTrackOutput[0]; sampleQueues = new DefaultTrackOutput[0];
length = C.LENGTH_UNBOUNDED; length = C.LENGTH_UNBOUNDED;
} }
/**
* 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).getConstructor().newInstance();
} catch (Exception e) {
// Should never happen.
throw new IllegalStateException("Unexpected error creating default extractor", e);
}
}
return extractors;
}
// SampleSource implementation. // SampleSource implementation.
@Override @Override
......
/*
* 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.extractor;
/**
* Factory for arrays of {@link Extractor}s.
*/
public interface ExtractorsFactory {
/**
* Returns an array of new {@link Extractor} instances.
*/
Extractor[] createExtractors();
}
...@@ -18,6 +18,7 @@ package com.google.android.exoplayer.extractor.flv; ...@@ -18,6 +18,7 @@ package com.google.android.exoplayer.extractor.flv;
import com.google.android.exoplayer.extractor.Extractor; import com.google.android.exoplayer.extractor.Extractor;
import com.google.android.exoplayer.extractor.ExtractorInput; import com.google.android.exoplayer.extractor.ExtractorInput;
import com.google.android.exoplayer.extractor.ExtractorOutput; import com.google.android.exoplayer.extractor.ExtractorOutput;
import com.google.android.exoplayer.extractor.ExtractorsFactory;
import com.google.android.exoplayer.extractor.PositionHolder; import com.google.android.exoplayer.extractor.PositionHolder;
import com.google.android.exoplayer.extractor.SeekMap; import com.google.android.exoplayer.extractor.SeekMap;
import com.google.android.exoplayer.util.ParsableByteArray; import com.google.android.exoplayer.util.ParsableByteArray;
...@@ -30,6 +31,18 @@ import java.io.IOException; ...@@ -30,6 +31,18 @@ import java.io.IOException;
*/ */
public final class FlvExtractor implements Extractor, SeekMap { public final class FlvExtractor implements Extractor, SeekMap {
/**
* Factory that returns one extractor which is a {@link FlvExtractor}.
*/
public static final class Factory implements ExtractorsFactory {
@Override
public Extractor[] createExtractors() {
return new Extractor[] {new FlvExtractor()};
}
}
// Header sizes. // Header sizes.
private static final int FLV_HEADER_SIZE = 9; private static final int FLV_HEADER_SIZE = 9;
private static final int FLV_TAG_HEADER_SIZE = 11; private static final int FLV_TAG_HEADER_SIZE = 11;
......
...@@ -24,6 +24,7 @@ import com.google.android.exoplayer.extractor.ChunkIndex; ...@@ -24,6 +24,7 @@ import com.google.android.exoplayer.extractor.ChunkIndex;
import com.google.android.exoplayer.extractor.Extractor; import com.google.android.exoplayer.extractor.Extractor;
import com.google.android.exoplayer.extractor.ExtractorInput; import com.google.android.exoplayer.extractor.ExtractorInput;
import com.google.android.exoplayer.extractor.ExtractorOutput; import com.google.android.exoplayer.extractor.ExtractorOutput;
import com.google.android.exoplayer.extractor.ExtractorsFactory;
import com.google.android.exoplayer.extractor.PositionHolder; import com.google.android.exoplayer.extractor.PositionHolder;
import com.google.android.exoplayer.extractor.SeekMap; import com.google.android.exoplayer.extractor.SeekMap;
import com.google.android.exoplayer.extractor.TrackOutput; import com.google.android.exoplayer.extractor.TrackOutput;
...@@ -51,6 +52,18 @@ import java.util.UUID; ...@@ -51,6 +52,18 @@ import java.util.UUID;
*/ */
public final class MatroskaExtractor implements Extractor { public final class MatroskaExtractor implements Extractor {
/**
* Factory that returns one extractor which is a {@link MatroskaExtractor}.
*/
public static final class Factory implements ExtractorsFactory {
@Override
public Extractor[] createExtractors() {
return new Extractor[] {new MatroskaExtractor()};
}
}
private static final int BLOCK_STATE_START = 0; private static final int BLOCK_STATE_START = 0;
private static final int BLOCK_STATE_HEADER = 1; private static final int BLOCK_STATE_HEADER = 1;
private static final int BLOCK_STATE_DATA = 2; private static final int BLOCK_STATE_DATA = 2;
......
...@@ -21,6 +21,7 @@ import com.google.android.exoplayer.ParserException; ...@@ -21,6 +21,7 @@ import com.google.android.exoplayer.ParserException;
import com.google.android.exoplayer.extractor.Extractor; import com.google.android.exoplayer.extractor.Extractor;
import com.google.android.exoplayer.extractor.ExtractorInput; import com.google.android.exoplayer.extractor.ExtractorInput;
import com.google.android.exoplayer.extractor.ExtractorOutput; import com.google.android.exoplayer.extractor.ExtractorOutput;
import com.google.android.exoplayer.extractor.ExtractorsFactory;
import com.google.android.exoplayer.extractor.GaplessInfoHolder; import com.google.android.exoplayer.extractor.GaplessInfoHolder;
import com.google.android.exoplayer.extractor.PositionHolder; import com.google.android.exoplayer.extractor.PositionHolder;
import com.google.android.exoplayer.extractor.SeekMap; import com.google.android.exoplayer.extractor.SeekMap;
...@@ -38,6 +39,18 @@ import java.io.IOException; ...@@ -38,6 +39,18 @@ import java.io.IOException;
public final class Mp3Extractor implements Extractor { public final class Mp3Extractor implements Extractor {
/** /**
* Factory that returns one extractor which is an {@link Mp3Extractor}.
*/
public static final class Factory implements ExtractorsFactory {
@Override
public Extractor[] createExtractors() {
return new Extractor[] {new Mp3Extractor()};
}
}
/**
* The maximum number of bytes to search when synchronizing, before giving up. * The maximum number of bytes to search when synchronizing, before giving up.
*/ */
private static final int MAX_SYNC_BYTES = 128 * 1024; private static final int MAX_SYNC_BYTES = 128 * 1024;
......
...@@ -23,6 +23,7 @@ import com.google.android.exoplayer.extractor.ChunkIndex; ...@@ -23,6 +23,7 @@ import com.google.android.exoplayer.extractor.ChunkIndex;
import com.google.android.exoplayer.extractor.Extractor; import com.google.android.exoplayer.extractor.Extractor;
import com.google.android.exoplayer.extractor.ExtractorInput; import com.google.android.exoplayer.extractor.ExtractorInput;
import com.google.android.exoplayer.extractor.ExtractorOutput; import com.google.android.exoplayer.extractor.ExtractorOutput;
import com.google.android.exoplayer.extractor.ExtractorsFactory;
import com.google.android.exoplayer.extractor.PositionHolder; import com.google.android.exoplayer.extractor.PositionHolder;
import com.google.android.exoplayer.extractor.SeekMap; import com.google.android.exoplayer.extractor.SeekMap;
import com.google.android.exoplayer.extractor.TrackOutput; import com.google.android.exoplayer.extractor.TrackOutput;
...@@ -50,6 +51,18 @@ import java.util.UUID; ...@@ -50,6 +51,18 @@ import java.util.UUID;
*/ */
public final class FragmentedMp4Extractor implements Extractor { public final class FragmentedMp4Extractor implements Extractor {
/**
* Factory that returns one extractor which is a {@link FragmentedMp4Extractor}.
*/
public static final class Factory implements ExtractorsFactory {
@Override
public Extractor[] createExtractors() {
return new Extractor[] {new FragmentedMp4Extractor()};
}
}
private static final String TAG = "FragmentedMp4Extractor"; private static final String TAG = "FragmentedMp4Extractor";
private static final int SAMPLE_GROUP_TYPE_seig = Util.getIntegerCodeForString("seig"); private static final int SAMPLE_GROUP_TYPE_seig = Util.getIntegerCodeForString("seig");
......
...@@ -21,6 +21,7 @@ import com.google.android.exoplayer.ParserException; ...@@ -21,6 +21,7 @@ import com.google.android.exoplayer.ParserException;
import com.google.android.exoplayer.extractor.Extractor; import com.google.android.exoplayer.extractor.Extractor;
import com.google.android.exoplayer.extractor.ExtractorInput; import com.google.android.exoplayer.extractor.ExtractorInput;
import com.google.android.exoplayer.extractor.ExtractorOutput; import com.google.android.exoplayer.extractor.ExtractorOutput;
import com.google.android.exoplayer.extractor.ExtractorsFactory;
import com.google.android.exoplayer.extractor.GaplessInfoHolder; import com.google.android.exoplayer.extractor.GaplessInfoHolder;
import com.google.android.exoplayer.extractor.PositionHolder; import com.google.android.exoplayer.extractor.PositionHolder;
import com.google.android.exoplayer.extractor.SeekMap; import com.google.android.exoplayer.extractor.SeekMap;
...@@ -41,6 +42,18 @@ import java.util.Stack; ...@@ -41,6 +42,18 @@ import java.util.Stack;
*/ */
public final class Mp4Extractor implements Extractor, SeekMap { public final class Mp4Extractor implements Extractor, SeekMap {
/**
* Factory that returns one extractor which is an {@link Mp4Extractor}.
*/
public static final class Factory implements ExtractorsFactory {
@Override
public Extractor[] createExtractors() {
return new Extractor[] {new Mp4Extractor()};
}
}
// Parser states. // Parser states.
private static final int STATE_AFTER_SEEK = 0; private static final int STATE_AFTER_SEEK = 0;
private static final int STATE_READING_ATOM_HEADER = 1; private static final int STATE_READING_ATOM_HEADER = 1;
......
...@@ -19,6 +19,7 @@ import com.google.android.exoplayer.ParserException; ...@@ -19,6 +19,7 @@ import com.google.android.exoplayer.ParserException;
import com.google.android.exoplayer.extractor.Extractor; import com.google.android.exoplayer.extractor.Extractor;
import com.google.android.exoplayer.extractor.ExtractorInput; import com.google.android.exoplayer.extractor.ExtractorInput;
import com.google.android.exoplayer.extractor.ExtractorOutput; import com.google.android.exoplayer.extractor.ExtractorOutput;
import com.google.android.exoplayer.extractor.ExtractorsFactory;
import com.google.android.exoplayer.extractor.PositionHolder; import com.google.android.exoplayer.extractor.PositionHolder;
import com.google.android.exoplayer.extractor.TrackOutput; import com.google.android.exoplayer.extractor.TrackOutput;
import com.google.android.exoplayer.util.ParsableByteArray; import com.google.android.exoplayer.util.ParsableByteArray;
...@@ -30,6 +31,18 @@ import java.io.IOException; ...@@ -30,6 +31,18 @@ import java.io.IOException;
*/ */
public class OggExtractor implements Extractor { public class OggExtractor implements Extractor {
/**
* Factory that returns one extractor which is an {@link OggExtractor}.
*/
public static final class Factory implements ExtractorsFactory {
@Override
public Extractor[] createExtractors() {
return new Extractor[] {new OggExtractor()};
}
}
private static final int MAX_VERIFICATION_BYTES = 8; private static final int MAX_VERIFICATION_BYTES = 8;
private StreamReader streamReader; private StreamReader streamReader;
......
...@@ -19,6 +19,7 @@ import com.google.android.exoplayer.C; ...@@ -19,6 +19,7 @@ import com.google.android.exoplayer.C;
import com.google.android.exoplayer.extractor.Extractor; import com.google.android.exoplayer.extractor.Extractor;
import com.google.android.exoplayer.extractor.ExtractorInput; import com.google.android.exoplayer.extractor.ExtractorInput;
import com.google.android.exoplayer.extractor.ExtractorOutput; import com.google.android.exoplayer.extractor.ExtractorOutput;
import com.google.android.exoplayer.extractor.ExtractorsFactory;
import com.google.android.exoplayer.extractor.PositionHolder; import com.google.android.exoplayer.extractor.PositionHolder;
import com.google.android.exoplayer.extractor.SeekMap; import com.google.android.exoplayer.extractor.SeekMap;
import com.google.android.exoplayer.util.ParsableBitArray; import com.google.android.exoplayer.util.ParsableBitArray;
...@@ -33,6 +34,18 @@ import java.io.IOException; ...@@ -33,6 +34,18 @@ import java.io.IOException;
*/ */
public final class AdtsExtractor implements Extractor { public final class AdtsExtractor implements Extractor {
/**
* Factory that returns one extractor which is an {@link AdtsExtractor}.
*/
public static final class Factory implements ExtractorsFactory {
@Override
public Extractor[] createExtractors() {
return new Extractor[] {new AdtsExtractor()};
}
}
private static final int MAX_PACKET_SIZE = 200; private static final int MAX_PACKET_SIZE = 200;
private static final int ID3_TAG = Util.getIntegerCodeForString("ID3"); private static final int ID3_TAG = Util.getIntegerCodeForString("ID3");
/** /**
......
...@@ -19,6 +19,7 @@ import com.google.android.exoplayer.C; ...@@ -19,6 +19,7 @@ import com.google.android.exoplayer.C;
import com.google.android.exoplayer.extractor.Extractor; import com.google.android.exoplayer.extractor.Extractor;
import com.google.android.exoplayer.extractor.ExtractorInput; import com.google.android.exoplayer.extractor.ExtractorInput;
import com.google.android.exoplayer.extractor.ExtractorOutput; import com.google.android.exoplayer.extractor.ExtractorOutput;
import com.google.android.exoplayer.extractor.ExtractorsFactory;
import com.google.android.exoplayer.extractor.PositionHolder; import com.google.android.exoplayer.extractor.PositionHolder;
import com.google.android.exoplayer.extractor.SeekMap; import com.google.android.exoplayer.extractor.SeekMap;
import com.google.android.exoplayer.util.ParsableBitArray; import com.google.android.exoplayer.util.ParsableBitArray;
...@@ -33,6 +34,18 @@ import java.io.IOException; ...@@ -33,6 +34,18 @@ import java.io.IOException;
*/ */
public final class PsExtractor implements Extractor { public final class PsExtractor implements Extractor {
/**
* Factory that returns one extractor which is a {@link PsExtractor}.
*/
public static final class Factory implements ExtractorsFactory {
@Override
public Extractor[] createExtractors() {
return new Extractor[] {new PsExtractor()};
}
}
private static final int PACK_START_CODE = 0x000001BA; private static final int PACK_START_CODE = 0x000001BA;
private static final int SYSTEM_HEADER_START_CODE = 0x000001BB; private static final int SYSTEM_HEADER_START_CODE = 0x000001BB;
private static final int PACKET_START_CODE_PREFIX = 0x000001; private static final int PACKET_START_CODE_PREFIX = 0x000001;
......
...@@ -20,6 +20,7 @@ import com.google.android.exoplayer.extractor.DummyTrackOutput; ...@@ -20,6 +20,7 @@ import com.google.android.exoplayer.extractor.DummyTrackOutput;
import com.google.android.exoplayer.extractor.Extractor; import com.google.android.exoplayer.extractor.Extractor;
import com.google.android.exoplayer.extractor.ExtractorInput; import com.google.android.exoplayer.extractor.ExtractorInput;
import com.google.android.exoplayer.extractor.ExtractorOutput; import com.google.android.exoplayer.extractor.ExtractorOutput;
import com.google.android.exoplayer.extractor.ExtractorsFactory;
import com.google.android.exoplayer.extractor.PositionHolder; import com.google.android.exoplayer.extractor.PositionHolder;
import com.google.android.exoplayer.extractor.SeekMap; import com.google.android.exoplayer.extractor.SeekMap;
import com.google.android.exoplayer.util.Assertions; import com.google.android.exoplayer.util.Assertions;
...@@ -38,6 +39,18 @@ import java.io.IOException; ...@@ -38,6 +39,18 @@ import java.io.IOException;
*/ */
public final class TsExtractor implements Extractor { public final class TsExtractor implements Extractor {
/**
* Factory that returns one extractor which is a {@link TsExtractor}.
*/
public static final class Factory implements ExtractorsFactory {
@Override
public Extractor[] createExtractors() {
return new Extractor[] {new TsExtractor()};
}
}
public static final int WORKAROUND_ALLOW_NON_IDR_KEYFRAMES = 1; public static final int WORKAROUND_ALLOW_NON_IDR_KEYFRAMES = 1;
public static final int WORKAROUND_IGNORE_AAC_STREAM = 2; public static final int WORKAROUND_IGNORE_AAC_STREAM = 2;
public static final int WORKAROUND_IGNORE_H264_STREAM = 4; public static final int WORKAROUND_IGNORE_H264_STREAM = 4;
......
...@@ -21,6 +21,7 @@ import com.google.android.exoplayer.ParserException; ...@@ -21,6 +21,7 @@ import com.google.android.exoplayer.ParserException;
import com.google.android.exoplayer.extractor.Extractor; import com.google.android.exoplayer.extractor.Extractor;
import com.google.android.exoplayer.extractor.ExtractorInput; import com.google.android.exoplayer.extractor.ExtractorInput;
import com.google.android.exoplayer.extractor.ExtractorOutput; import com.google.android.exoplayer.extractor.ExtractorOutput;
import com.google.android.exoplayer.extractor.ExtractorsFactory;
import com.google.android.exoplayer.extractor.PositionHolder; import com.google.android.exoplayer.extractor.PositionHolder;
import com.google.android.exoplayer.extractor.SeekMap; import com.google.android.exoplayer.extractor.SeekMap;
import com.google.android.exoplayer.extractor.TrackOutput; import com.google.android.exoplayer.extractor.TrackOutput;
...@@ -31,6 +32,18 @@ import java.io.IOException; ...@@ -31,6 +32,18 @@ import java.io.IOException;
/** {@link Extractor} to extract samples from a WAV byte stream. */ /** {@link Extractor} to extract samples from a WAV byte stream. */
public final class WavExtractor implements Extractor, SeekMap { public final class WavExtractor implements Extractor, SeekMap {
/**
* Factory that returns one extractor which is a {@link WavExtractor}.
*/
public static final class Factory implements ExtractorsFactory {
@Override
public Extractor[] createExtractors() {
return new Extractor[] {new WavExtractor()};
}
}
/** Arbitrary maximum input size of 32KB, which is ~170ms of 16-bit stereo PCM audio at 48KHz. */ /** Arbitrary maximum input size of 32KB, which is ~170ms of 16-bit stereo PCM audio at 48KHz. */
private static final int MAX_INPUT_SIZE = 32 * 1024; private static final int MAX_INPUT_SIZE = 32 * 1024;
......
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