/* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.android.exoplayer; import java.io.IOException; /** * A source of media samples. * <p> * A {@link SampleSource} may expose one or multiple tracks. The number of tracks and each track's * media format can be queried using {@link SampleSourceReader#getTrackCount()} and * {@link SampleSourceReader#getFormat(int)} respectively. */ public interface SampleSource { /** * The end of stream has been reached. */ public static final int END_OF_STREAM = -1; /** * Neither a sample nor a format was read in full. This may be because insufficient data is * buffered upstream. If multiple tracks are enabled, this return value may indicate that the * next piece of data to be returned from the {@link SampleSource} corresponds to a different * track than the one for which data was requested. */ public static final int NOTHING_READ = -2; /** * A sample was read. */ public static final int SAMPLE_READ = -3; /** * A format was read. */ public static final int FORMAT_READ = -4; /** * A discontinuity in the sample stream. */ public static final int DISCONTINUITY_READ = -5; /** * A consumer of samples should call this method to register themselves and gain access to the * source through the returned {@link SampleSourceReader}. * <p> * {@link SampleSourceReader#release()} should be called on the returned object when access is no * longer required. * * @return A {@link SampleSourceReader} that provides access to the source. */ public SampleSourceReader register(); /** * An interface providing read access to a {@link SampleSource}. */ public interface SampleSourceReader { /** * If the source is currently having difficulty preparing or loading samples, then this method * throws the underlying error. Otherwise does nothing. * * @throws IOException The underlying error. */ public void maybeThrowError() throws IOException; /** * Prepares the source. * <p> * Preparation may require reading from the data source (e.g. to determine the available tracks * and formats). If insufficient data is available then the call will return {@code false} * rather than block. The method can be called repeatedly until the return value indicates * success. * * @param positionUs The player's current playback position. * @return True if the source was prepared, false otherwise. */ public boolean prepare(long positionUs); /** * Returns the number of tracks exposed by the source. * <p> * This method should only be called after the source has been prepared. * * @return The number of tracks. */ public int getTrackCount(); /** * Returns the format of the specified track. * <p> * Note that whilst the format of a track will remain constant, the format of the actual media * stream may change dynamically. An example of this is where the track is adaptive * (i.e. @link {@link MediaFormat#adaptive} is true). Hence the track formats returned through * this method should not be used to configure decoders. Decoder configuration should be * performed using the formats obtained when reading the media stream through calls to * {@link #readData(int, long, MediaFormatHolder, SampleHolder, boolean)}. * <p> * This method should only be called after the source has been prepared. * * @param track The track index. * @return The format of the specified track. */ public MediaFormat getFormat(int track); /** * Enable the specified track. This allows the track's format and samples to be read from * {@link #readData(int, long, MediaFormatHolder, SampleHolder, boolean)}. * <p> * This method should only be called after the source has been prepared, and when the specified * track is disabled. * * @param track The track to enable. * @param positionUs The player's current playback position. */ public void enable(int track, long positionUs); /** * Indicates to the source that it should still be buffering data for the specified track. * <p> * This method should only be called when the specified track is enabled. * * @param track The track to continue buffering. * @param positionUs The current playback position. * @return True if the track has available samples, or if the end of the stream has been * reached. False if more data needs to be buffered for samples to become available. */ public boolean continueBuffering(int track, long positionUs); /** * Attempts to read either a sample, a new format or or a discontinuity from the source. * <p> * This method should only be called when the specified track is enabled. * <p> * Note that where multiple tracks are enabled, {@link #NOTHING_READ} may be returned if the * next piece of data to be read from the {@link SampleSource} corresponds to a different track * than the one for which data was requested. * * @param track The track from which to read. * @param positionUs The current playback position. * @param formatHolder A {@link MediaFormatHolder} object to populate in the case of a new * format. * @param sampleHolder A {@link SampleHolder} object to populate in the case of a new sample. * If the caller requires the sample data then it must ensure that {@link SampleHolder#data} * references a valid output buffer. * @param onlyReadDiscontinuity Whether to only read a discontinuity. If true, only * {@link #DISCONTINUITY_READ} or {@link #NOTHING_READ} can be returned. * @return The result, which can be {@link #SAMPLE_READ}, {@link #FORMAT_READ}, * {@link #DISCONTINUITY_READ}, {@link #NOTHING_READ} or {@link #END_OF_STREAM}. */ public int readData(int track, long positionUs, MediaFormatHolder formatHolder, SampleHolder sampleHolder, boolean onlyReadDiscontinuity); /** * Seeks to the specified time in microseconds. * <p> * This method should only be called when at least one track is enabled. * * @param positionUs The seek position in microseconds. */ public void seekToUs(long positionUs); /** * Returns an estimate of the position up to which data is buffered. * <p> * This method should only be called when at least one track is enabled. * * @return An estimate of the absolute position in microseconds up to which data is buffered, * or {@link TrackRenderer#END_OF_TRACK_US} if data is buffered to the end of the stream, * or {@link TrackRenderer#UNKNOWN_TIME_US} if no estimate is available. */ public long getBufferedPositionUs(); /** * Disable the specified track. * <p> * This method should only be called when the specified track is enabled. * * @param track The track to disable. */ public void disable(int track); /** * Releases the {@link SampleSourceReader}. * <p> * This method should be called when access to the {@link SampleSource} is no longer required. */ public void release(); } }