Commit fb55254f by olly Committed by Oliver Woodman

Fix a bunch more Javadoc

Also inline a few methods/classes where they can be made
private and therefore be removed from the public API.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=130935090
parent e003c5b6
Showing with 419 additions and 270 deletions
...@@ -17,13 +17,14 @@ package com.google.android.exoplayer2.demo; ...@@ -17,13 +17,14 @@ package com.google.android.exoplayer2.demo;
import android.os.SystemClock; import android.os.SystemClock;
import android.util.Log; import android.util.Log;
import android.view.Surface;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.RendererCapabilities; import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.audio.AudioRendererEventListener;
import com.google.android.exoplayer2.decoder.DecoderCounters; import com.google.android.exoplayer2.decoder.DecoderCounters;
import com.google.android.exoplayer2.drm.StreamingDrmSessionManager; import com.google.android.exoplayer2.drm.StreamingDrmSessionManager;
import com.google.android.exoplayer2.metadata.MetadataRenderer; import com.google.android.exoplayer2.metadata.MetadataRenderer;
...@@ -41,6 +42,7 @@ import com.google.android.exoplayer2.trackselection.MappingTrackSelector; ...@@ -41,6 +42,7 @@ import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.TrackInfo; import com.google.android.exoplayer2.trackselection.MappingTrackSelector.TrackInfo;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.video.VideoRendererEventListener;
import java.io.IOException; import java.io.IOException;
import java.text.NumberFormat; import java.text.NumberFormat;
import java.util.List; import java.util.List;
...@@ -50,7 +52,7 @@ import java.util.Locale; ...@@ -50,7 +52,7 @@ import java.util.Locale;
* Logs player events using {@link Log}. * Logs player events using {@link Log}.
*/ */
/* package */ final class EventLogger implements ExoPlayer.EventListener, /* package */ final class EventLogger implements ExoPlayer.EventListener,
SimpleExoPlayer.DebugListener, AdaptiveMediaSourceEventListener, AudioRendererEventListener, VideoRendererEventListener, AdaptiveMediaSourceEventListener,
ExtractorMediaSource.EventListener, StreamingDrmSessionManager.EventListener, ExtractorMediaSource.EventListener, StreamingDrmSessionManager.EventListener,
MappingTrackSelector.EventListener, MetadataRenderer.Output<List<Id3Frame>> { MappingTrackSelector.EventListener, MetadataRenderer.Output<List<Id3Frame>> {
...@@ -184,7 +186,7 @@ import java.util.Locale; ...@@ -184,7 +186,7 @@ import java.util.Locale;
} }
} }
// SimpleExoPlayer.DebugListener // AudioRendererEventListener
@Override @Override
public void onAudioEnabled(DecoderCounters counters) { public void onAudioEnabled(DecoderCounters counters) {
...@@ -203,7 +205,7 @@ import java.util.Locale; ...@@ -203,7 +205,7 @@ import java.util.Locale;
} }
@Override @Override
public void onAudioFormatChanged(Format format) { public void onAudioInputFormatChanged(Format format) {
Log.d(TAG, "audioFormatChanged [" + getSessionTimeString() + ", " + getFormatString(format) Log.d(TAG, "audioFormatChanged [" + getSessionTimeString() + ", " + getFormatString(format)
+ "]"); + "]");
} }
...@@ -214,6 +216,14 @@ import java.util.Locale; ...@@ -214,6 +216,14 @@ import java.util.Locale;
} }
@Override @Override
public void onAudioTrackUnderrun(int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs) {
printInternalError("audioTrackUnderrun [" + bufferSize + ", " + bufferSizeMs + ", "
+ elapsedSinceLastFeedMs + "]", null);
}
// VideoRendererEventListener
@Override
public void onVideoEnabled(DecoderCounters counters) { public void onVideoEnabled(DecoderCounters counters) {
Log.d(TAG, "videoEnabled [" + getSessionTimeString() + "]"); Log.d(TAG, "videoEnabled [" + getSessionTimeString() + "]");
} }
...@@ -225,7 +235,7 @@ import java.util.Locale; ...@@ -225,7 +235,7 @@ import java.util.Locale;
} }
@Override @Override
public void onVideoFormatChanged(Format format) { public void onVideoInputFormatChanged(Format format) {
Log.d(TAG, "videoFormatChanged [" + getSessionTimeString() + ", " + getFormatString(format) Log.d(TAG, "videoFormatChanged [" + getSessionTimeString() + ", " + getFormatString(format)
+ "]"); + "]");
} }
...@@ -241,9 +251,14 @@ import java.util.Locale; ...@@ -241,9 +251,14 @@ import java.util.Locale;
} }
@Override @Override
public void onAudioTrackUnderrun(int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs) { public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees,
printInternalError("audioTrackUnderrun [" + bufferSize + ", " + bufferSizeMs + ", " float pixelWidthHeightRatio) {
+ elapsedSinceLastFeedMs + "]", null); // Do nothing.
}
@Override
public void onRenderedFirstFrame(Surface surface) {
// Do nothing.
} }
// StreamingDrmSessionManager.EventListener // StreamingDrmSessionManager.EventListener
......
...@@ -275,7 +275,8 @@ public class PlayerActivity extends Activity implements OnKeyListener, OnTouchLi ...@@ -275,7 +275,8 @@ public class PlayerActivity extends Activity implements OnKeyListener, OnTouchLi
drmSessionManager, preferExtensionDecoders); drmSessionManager, preferExtensionDecoders);
player.addListener(this); player.addListener(this);
player.addListener(eventLogger); player.addListener(eventLogger);
player.setDebugListener(eventLogger); player.setAudioDebugListener(eventLogger);
player.setVideoDebugListener(eventLogger);
player.setId3Output(eventLogger); player.setId3Output(eventLogger);
player.setTextOutput(subtitleView); player.setTextOutput(subtitleView);
player.setVideoListener(this); player.setVideoListener(this);
......
...@@ -242,9 +242,17 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities { ...@@ -242,9 +242,17 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities {
} }
/** /**
* Reads from the enabled upstream source. * Reads from the enabled upstream source. If the upstream source has been read to the end then
* {@link C#RESULT_BUFFER_READ} is only returned if {@link #setCurrentStreamIsFinal()} has been
* called. {@link C#RESULT_NOTHING_READ} is returned otherwise.
* *
* @see SampleStream#readData(FormatHolder, DecoderInputBuffer) * @see SampleStream#readData(FormatHolder, DecoderInputBuffer)
* @param formatHolder A {@link FormatHolder} to populate in the case of reading a format.
* @param buffer A {@link DecoderInputBuffer} to populate in the case of reading a sample or the
* end of the stream. If the end of the stream has been reached, the
* {@link C#BUFFER_FLAG_END_OF_STREAM} flag will be set on the buffer.
* @return The result, which can be {@link C#RESULT_NOTHING_READ}, {@link C#RESULT_FORMAT_READ} or
* {@link C#RESULT_BUFFER_READ}.
*/ */
protected final int readSource(FormatHolder formatHolder, DecoderInputBuffer buffer) { protected final int readSource(FormatHolder formatHolder, DecoderInputBuffer buffer) {
int result = stream.readData(formatHolder, buffer); int result = stream.readData(formatHolder, buffer);
......
...@@ -22,7 +22,7 @@ import com.google.android.exoplayer2.util.Util; ...@@ -22,7 +22,7 @@ import com.google.android.exoplayer2.util.Util;
import java.util.UUID; import java.util.UUID;
/** /**
* Defines constants that are generally useful throughout the library. * Defines constants used by the library.
*/ */
public final class C { public final class C {
......
...@@ -44,9 +44,9 @@ public final class DefaultLoadControl implements LoadControl { ...@@ -44,9 +44,9 @@ public final class DefaultLoadControl implements LoadControl {
public static final int DEFAULT_BUFFER_FOR_PLAYBACK_MS = 2500; public static final int DEFAULT_BUFFER_FOR_PLAYBACK_MS = 2500;
/** /**
* The default duration of media that must be buffered for playback to resume after a * The default duration of media that must be buffered for playback to resume after a rebuffer,
* player-invoked rebuffer (i.e. a rebuffer that occurs due to buffer depletion rather than a user * in milliseconds. A rebuffer is defined to be caused by buffer depletion rather than a user
* action), in milliseconds. * action.
*/ */
public static final int DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS = 5000; public static final int DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS = 5000;
...@@ -92,8 +92,8 @@ public final class DefaultLoadControl implements LoadControl { ...@@ -92,8 +92,8 @@ public final class DefaultLoadControl implements LoadControl {
* @param bufferForPlaybackMs The duration of media that must be buffered for playback to start or * @param bufferForPlaybackMs The duration of media that must be buffered for playback to start or
* resume following a user action such as a seek, in milliseconds. * resume following a user action such as a seek, in milliseconds.
* @param bufferForPlaybackAfterRebufferMs The default duration of media that must be buffered for * @param bufferForPlaybackAfterRebufferMs The default duration of media that must be buffered for
* playback to resume after a player-invoked rebuffer (i.e. a rebuffer that occurs due to * playback to resume after a rebuffer, in milliseconds. A rebuffer is defined to be caused by
* buffer depletion rather than a user action), in milliseconds. * buffer depletion rather than a user action.
*/ */
public DefaultLoadControl(DefaultAllocator allocator, int minBufferMs, int maxBufferMs, public DefaultLoadControl(DefaultAllocator allocator, int minBufferMs, int maxBufferMs,
long bufferForPlaybackMs, long bufferForPlaybackAfterRebufferMs) { long bufferForPlaybackMs, long bufferForPlaybackAfterRebufferMs) {
...@@ -105,7 +105,7 @@ public final class DefaultLoadControl implements LoadControl { ...@@ -105,7 +105,7 @@ public final class DefaultLoadControl implements LoadControl {
} }
@Override @Override
public void onTrackSelections(Renderer[] renderers, TrackGroupArray trackGroups, public void onTracksSelected(Renderer[] renderers, TrackGroupArray trackGroups,
TrackSelectionArray trackSelections) { TrackSelectionArray trackSelections) {
targetBufferSize = 0; targetBufferSize = 0;
for (int i = 0; i < renderers.length; i++) { for (int i = 0; i < renderers.length; i++) {
...@@ -117,7 +117,7 @@ public final class DefaultLoadControl implements LoadControl { ...@@ -117,7 +117,7 @@ public final class DefaultLoadControl implements LoadControl {
} }
@Override @Override
public void reset() { public void onTracksDisabled() {
targetBufferSize = 0; targetBufferSize = 0;
isBuffering = false; isBuffering = false;
} }
......
...@@ -54,14 +54,33 @@ public final class ExoPlaybackException extends Exception { ...@@ -54,14 +54,33 @@ public final class ExoPlaybackException extends Exception {
*/ */
public final int rendererIndex; public final int rendererIndex;
/**
* Creates an instance of type {@link #TYPE_RENDERER}.
*
* @param cause The cause of the failure.
* @param rendererIndex The index of the renderer in which the failure occurred.
* @return The created instance.
*/
public static ExoPlaybackException createForRenderer(Exception cause, int rendererIndex) { public static ExoPlaybackException createForRenderer(Exception cause, int rendererIndex) {
return new ExoPlaybackException(TYPE_RENDERER, null, cause, rendererIndex); return new ExoPlaybackException(TYPE_RENDERER, null, cause, rendererIndex);
} }
/**
* Creates an instance of type {@link #TYPE_SOURCE}.
*
* @param cause The cause of the failure.
* @return The created instance.
*/
public static ExoPlaybackException createForSource(IOException cause) { public static ExoPlaybackException createForSource(IOException cause) {
return new ExoPlaybackException(TYPE_SOURCE, null, cause, C.INDEX_UNSET); return new ExoPlaybackException(TYPE_SOURCE, null, cause, C.INDEX_UNSET);
} }
/**
* Creates an instance of type {@link #TYPE_UNEXPECTED}.
*
* @param cause The cause of the failure.
* @return The created instance.
*/
/* package */ static ExoPlaybackException createForUnexpected(RuntimeException cause) { /* package */ static ExoPlaybackException createForUnexpected(RuntimeException cause) {
return new ExoPlaybackException(TYPE_UNEXPECTED, null, cause, C.INDEX_UNSET); return new ExoPlaybackException(TYPE_UNEXPECTED, null, cause, C.INDEX_UNSET);
} }
...@@ -74,6 +93,8 @@ public final class ExoPlaybackException extends Exception { ...@@ -74,6 +93,8 @@ public final class ExoPlaybackException extends Exception {
/** /**
* Retrieves the underlying error when {@link #type} is {@link #TYPE_SOURCE}. * Retrieves the underlying error when {@link #type} is {@link #TYPE_SOURCE}.
*
* @throws IllegalStateException If {@link #type} is not {@link #TYPE_SOURCE}.
*/ */
public IOException getSourceException() { public IOException getSourceException() {
Assertions.checkState(type == TYPE_SOURCE); Assertions.checkState(type == TYPE_SOURCE);
...@@ -82,6 +103,8 @@ public final class ExoPlaybackException extends Exception { ...@@ -82,6 +103,8 @@ public final class ExoPlaybackException extends Exception {
/** /**
* Retrieves the underlying error when {@link #type} is {@link #TYPE_RENDERER}. * Retrieves the underlying error when {@link #type} is {@link #TYPE_RENDERER}.
*
* @throws IllegalStateException If {@link #type} is not {@link #TYPE_RENDERER}.
*/ */
public Exception getRendererException() { public Exception getRendererException() {
Assertions.checkState(type == TYPE_RENDERER); Assertions.checkState(type == TYPE_RENDERER);
...@@ -90,6 +113,8 @@ public final class ExoPlaybackException extends Exception { ...@@ -90,6 +113,8 @@ public final class ExoPlaybackException extends Exception {
/** /**
* Retrieves the underlying error when {@link #type} is {@link #TYPE_UNEXPECTED}. * Retrieves the underlying error when {@link #type} is {@link #TYPE_UNEXPECTED}.
*
* @throws IllegalStateException If {@link #type} is not {@link #TYPE_UNEXPECTED}.
*/ */
public RuntimeException getUnexpectedException() { public RuntimeException getUnexpectedException() {
Assertions.checkState(type == TYPE_UNEXPECTED); Assertions.checkState(type == TYPE_UNEXPECTED);
......
...@@ -157,8 +157,8 @@ public interface ExoPlayer { ...@@ -157,8 +157,8 @@ public interface ExoPlayer {
/** /**
* Handles a message delivered to the component. Called on the playback thread. * Handles a message delivered to the component. Called on the playback thread.
* *
* @param messageType An integer identifying the type of message. * @param messageType The message type.
* @param message The message object. * @param message The message.
* @throws ExoPlaybackException If an error occurred whilst handling the message. * @throws ExoPlaybackException If an error occurred whilst handling the message.
*/ */
void handleMessage(int messageType, Object message) throws ExoPlaybackException; void handleMessage(int messageType, Object message) throws ExoPlaybackException;
...@@ -170,14 +170,23 @@ public interface ExoPlayer { ...@@ -170,14 +170,23 @@ public interface ExoPlayer {
*/ */
final class ExoPlayerMessage { final class ExoPlayerMessage {
/**
* The target to receive the message.
*/
public final ExoPlayerComponent target; public final ExoPlayerComponent target;
/**
* The type of the message.
*/
public final int messageType; public final int messageType;
/**
* The message.
*/
public final Object message; public final Object message;
/** /**
* @param target The target of the message. * @param target The target of the message.
* @param messageType An integer identifying the type of message. * @param messageType The message type.
* @param message The message object. * @param message The message.
*/ */
public ExoPlayerMessage(ExoPlayerComponent target, int messageType, Object message) { public ExoPlayerMessage(ExoPlayerComponent target, int messageType, Object message) {
this.target = target; this.target = target;
......
...@@ -21,7 +21,7 @@ import com.google.android.exoplayer2.drm.DrmSessionManager; ...@@ -21,7 +21,7 @@ import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.trackselection.TrackSelector; import com.google.android.exoplayer2.trackselection.TrackSelector;
/** /**
* A factory for instantiating {@link ExoPlayer} instances. * A factory for {@link ExoPlayer} instances.
*/ */
public final class ExoPlayerFactory { public final class ExoPlayerFactory {
...@@ -34,9 +34,8 @@ public final class ExoPlayerFactory { ...@@ -34,9 +34,8 @@ public final class ExoPlayerFactory {
private ExoPlayerFactory() {} private ExoPlayerFactory() {}
/** /**
* Obtains a {@link SimpleExoPlayer} instance. * Creates a {@link SimpleExoPlayer} instance. Must be called from a thread that has an associated
* <p> * {@link Looper}.
* Must be called from a thread that has an associated {@link Looper}.
* *
* @param context A {@link Context}. * @param context A {@link Context}.
* @param trackSelector The {@link TrackSelector} that will be used by the instance. * @param trackSelector The {@link TrackSelector} that will be used by the instance.
...@@ -46,9 +45,8 @@ public final class ExoPlayerFactory { ...@@ -46,9 +45,8 @@ public final class ExoPlayerFactory {
} }
/** /**
* Obtains a {@link SimpleExoPlayer} instance. * Creates a {@link SimpleExoPlayer} instance. Must be called from a thread that has an associated
* <p> * {@link Looper}.
* Must be called from a thread that has an associated {@link Looper}.
* *
* @param context A {@link Context}. * @param context A {@link Context}.
* @param trackSelector The {@link TrackSelector} that will be used by the instance. * @param trackSelector The {@link TrackSelector} that will be used by the instance.
...@@ -62,9 +60,8 @@ public final class ExoPlayerFactory { ...@@ -62,9 +60,8 @@ public final class ExoPlayerFactory {
} }
/** /**
* Obtains a {@link SimpleExoPlayer} instance. * Creates a {@link SimpleExoPlayer} instance. Must be called from a thread that has an associated
* <p> * {@link Looper}.
* Must be called from a thread that has an associated {@link Looper}.
* *
* @param context A {@link Context}. * @param context A {@link Context}.
* @param trackSelector The {@link TrackSelector} that will be used by the instance. * @param trackSelector The {@link TrackSelector} that will be used by the instance.
...@@ -83,9 +80,8 @@ public final class ExoPlayerFactory { ...@@ -83,9 +80,8 @@ public final class ExoPlayerFactory {
} }
/** /**
* Obtains a {@link SimpleExoPlayer} instance. * Creates a {@link SimpleExoPlayer} instance. Must be called from a thread that has an associated
* <p> * {@link Looper}.
* Must be called from a thread that has an associated {@link Looper}.
* *
* @param context A {@link Context}. * @param context A {@link Context}.
* @param trackSelector The {@link TrackSelector} that will be used by the instance. * @param trackSelector The {@link TrackSelector} that will be used by the instance.
...@@ -106,9 +102,8 @@ public final class ExoPlayerFactory { ...@@ -106,9 +102,8 @@ public final class ExoPlayerFactory {
} }
/** /**
* Obtains an {@link ExoPlayer} instance. * Creates an {@link ExoPlayer} instance. Must be called from a thread that has an associated
* <p> * {@link Looper}.
* Must be called from a thread that has an associated {@link Looper}.
* *
* @param renderers The {@link Renderer}s that will be used by the instance. * @param renderers The {@link Renderer}s that will be used by the instance.
* @param trackSelector The {@link TrackSelector} that will be used by the instance. * @param trackSelector The {@link TrackSelector} that will be used by the instance.
...@@ -118,9 +113,8 @@ public final class ExoPlayerFactory { ...@@ -118,9 +113,8 @@ public final class ExoPlayerFactory {
} }
/** /**
* Obtains an {@link ExoPlayer} instance. * Creates an {@link ExoPlayer} instance. Must be called from a thread that has an associated
* <p> * {@link Looper}.
* Must be called from a thread that has an associated {@link Looper}.
* *
* @param renderers The {@link Renderer}s that will be used by the instance. * @param renderers The {@link Renderer}s that will be used by the instance.
* @param trackSelector The {@link TrackSelector} that will be used by the instance. * @param trackSelector The {@link TrackSelector} that will be used by the instance.
......
...@@ -636,7 +636,7 @@ import java.io.IOException; ...@@ -636,7 +636,7 @@ import java.io.IOException;
loadingPeriod = null; loadingPeriod = null;
timeline = null; timeline = null;
bufferAheadPeriodCount = 0; bufferAheadPeriodCount = 0;
loadControl.reset(); loadControl.onTracksDisabled();
setIsLoading(false); setIsLoading(false);
} }
...@@ -1253,7 +1253,7 @@ import java.io.IOException; ...@@ -1253,7 +1253,7 @@ import java.io.IOException;
} }
// The track selection has changed. // The track selection has changed.
loadControl.onTrackSelections(renderers, mediaPeriod.getTrackGroups(), trackSelections); loadControl.onTracksSelected(renderers, mediaPeriod.getTrackGroups(), trackSelections);
return positionUs; return positionUs;
} }
......
...@@ -18,12 +18,12 @@ package com.google.android.exoplayer2; ...@@ -18,12 +18,12 @@ package com.google.android.exoplayer2;
/** /**
* Information about the ExoPlayer library. * Information about the ExoPlayer library.
*/ */
public final class ExoPlayerLibraryInfo { public interface ExoPlayerLibraryInfo {
/** /**
* The version of the library, expressed as a string. * The version of the library, expressed as a string.
*/ */
public static final String VERSION = "2.0.0"; String VERSION = "2.0.0";
/** /**
* The version of the library, expressed as an integer. * The version of the library, expressed as an integer.
...@@ -32,20 +32,18 @@ public final class ExoPlayerLibraryInfo { ...@@ -32,20 +32,18 @@ public final class ExoPlayerLibraryInfo {
* corresponding integer version 1002003 (001-002-003), and "123.45.6" has the corresponding * corresponding integer version 1002003 (001-002-003), and "123.45.6" has the corresponding
* integer version 123045006 (123-045-006). * integer version 123045006 (123-045-006).
*/ */
public static final int VERSION_INT = 2000000; int VERSION_INT = 2000000;
/** /**
* Whether the library was compiled with {@link com.google.android.exoplayer2.util.Assertions} * Whether the library was compiled with {@link com.google.android.exoplayer2.util.Assertions}
* checks enabled. * checks enabled.
*/ */
public static final boolean ASSERTIONS_ENABLED = true; boolean ASSERTIONS_ENABLED = true;
/** /**
* Whether the library was compiled with {@link com.google.android.exoplayer2.util.TraceUtil} * Whether the library was compiled with {@link com.google.android.exoplayer2.util.TraceUtil}
* trace enabled. * trace enabled.
*/ */
public static final boolean TRACE_ENABLED = true; boolean TRACE_ENABLED = true;
private ExoPlayerLibraryInfo() {}
} }
...@@ -27,7 +27,6 @@ import java.nio.ByteBuffer; ...@@ -27,7 +27,6 @@ import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.List; import java.util.List;
/** /**
...@@ -36,24 +35,14 @@ import java.util.List; ...@@ -36,24 +35,14 @@ import java.util.List;
public final class Format implements Parcelable { public final class Format implements Parcelable {
/** /**
* Sorts {@link Format} objects in order of decreasing bandwidth. * A value for various fields to indicate that the field's value is unknown or not applicable.
*/ */
public static final class DecreasingBandwidthComparator implements Comparator<Format> {
@Override
public int compare(Format a, Format b) {
return b.bitrate - a.bitrate;
}
}
public static final int NO_VALUE = -1; public static final int NO_VALUE = -1;
/** /**
* Indicates that the track should be selected if user preferences do not state otherwise. * Indicates that the track should be selected if user preferences do not state otherwise.
*/ */
public static final int SELECTION_FLAG_DEFAULT = 1; public static final int SELECTION_FLAG_DEFAULT = 1;
/** /**
* Indicates that the track must be displayed. Only applies to text tracks. * Indicates that the track must be displayed. Only applies to text tracks.
*/ */
...@@ -595,6 +584,9 @@ public final class Format implements Parcelable { ...@@ -595,6 +584,9 @@ public final class Format implements Parcelable {
dest.writeParcelable(drmInitData, 0); dest.writeParcelable(drmInitData, 0);
} }
/**
* {@link Creator} implementation.
*/
public static final Creator<Format> CREATOR = new Creator<Format>() { public static final Creator<Format> CREATOR = new Creator<Format>() {
@Override @Override
......
...@@ -16,12 +16,12 @@ ...@@ -16,12 +16,12 @@
package com.google.android.exoplayer2; package com.google.android.exoplayer2;
/** /**
* Holds a {@link Format} and corresponding drm scheme initialization data. * Holds a {@link Format}.
*/ */
public final class FormatHolder { public final class FormatHolder {
/** /**
* The format of the media. * The held {@link Format}.
*/ */
public Format format; public Format format;
......
...@@ -30,16 +30,16 @@ public interface LoadControl { ...@@ -30,16 +30,16 @@ public interface LoadControl {
* Called by the player when a track selection occurs. * Called by the player when a track selection occurs.
* *
* @param renderers The renderers. * @param renderers The renderers.
* @param trackGroups The available {@link TrackGroup}s. * @param trackGroups The {@link TrackGroup}s from which the selection was made.
* @param trackSelections The {@link TrackSelection}s that were made. * @param trackSelections The {@link TrackSelection}s that were made.
*/ */
void onTrackSelections(Renderer[] renderers, TrackGroupArray trackGroups, void onTracksSelected(Renderer[] renderers, TrackGroupArray trackGroups,
TrackSelectionArray trackSelections); TrackSelectionArray trackSelections);
/** /**
* Called by the player when a reset occurs, meaning all renderers have been disabled. * Called by the player when all tracks are disabled.
*/ */
void reset(); void onTracksDisabled();
/** /**
* Returns the {@link Allocator} that should be used to obtain media buffer allocations. * Returns the {@link Allocator} that should be used to obtain media buffer allocations.
...@@ -51,7 +51,9 @@ public interface LoadControl { ...@@ -51,7 +51,9 @@ public interface LoadControl {
* started or resumed. * started or resumed.
* *
* @param bufferedDurationUs The duration of media that's currently buffered. * @param bufferedDurationUs The duration of media that's currently buffered.
* @param rebuffering Whether the player is re-buffering. * @param rebuffering Whether the player is rebuffering. A rebuffer is defined to be caused by
* buffer depletion rather than a user action. Hence this parameter is false during initial
* buffering and when buffering as a result of a seek operation.
* @return Whether playback should be allowed to start or resume. * @return Whether playback should be allowed to start or resume.
*/ */
boolean shouldStartPlayback(long bufferedDurationUs, boolean rebuffering); boolean shouldStartPlayback(long bufferedDurationUs, boolean rebuffering);
......
...@@ -18,7 +18,7 @@ package com.google.android.exoplayer2; ...@@ -18,7 +18,7 @@ package com.google.android.exoplayer2;
import java.io.IOException; import java.io.IOException;
/** /**
* Thrown when an error occurs parsing loaded data. * Thrown when an error occurs parsing media data and metadata.
*/ */
public class ParserException extends IOException { public class ParserException extends IOException {
...@@ -26,14 +26,24 @@ public class ParserException extends IOException { ...@@ -26,14 +26,24 @@ public class ParserException extends IOException {
super(); super();
} }
/**
* @param message The detail message for the exception.
*/
public ParserException(String message) { public ParserException(String message) {
super(message); super(message);
} }
/**
* @param cause The cause for the exception.
*/
public ParserException(Throwable cause) { public ParserException(Throwable cause) {
super(cause); super(cause);
} }
/**
* @param message The detail message for the exception.
* @param cause The cause for the exception.
*/
public ParserException(String message, Throwable cause) { public ParserException(String message, Throwable cause) {
super(message, cause); super(message, cause);
} }
......
...@@ -21,15 +21,14 @@ import com.google.android.exoplayer2.util.MediaClock; ...@@ -21,15 +21,14 @@ import com.google.android.exoplayer2.util.MediaClock;
import java.io.IOException; import java.io.IOException;
/** /**
* Renders media samples read from a {@link SampleStream}. * Renders media read from a {@link SampleStream}.
* <p> * <p>
* Internally, a renderer's lifecycle is managed by the owning {@link ExoPlayer}. The player will * Internally, a renderer's lifecycle is managed by the owning {@link ExoPlayer}. The renderer is
* transition its renderers through various states as the overall playback state changes. The valid * transitioned through various states as the overall playback state changes. The valid state
* state transitions are shown below, annotated with the methods that are called during each * transitions are shown below, annotated with the methods that are called during each transition.
* transition. * <p align="center">
* <p align="center"><img src="doc-files/renderer-states.png" * <img src="doc-files/renderer-states.svg" alt="Renderer state transitions">
* alt="Renderer state transitions" * </p>
* border="0"></p>
*/ */
public interface Renderer extends ExoPlayerComponent { public interface Renderer extends ExoPlayerComponent {
...@@ -38,8 +37,8 @@ public interface Renderer extends ExoPlayerComponent { ...@@ -38,8 +37,8 @@ public interface Renderer extends ExoPlayerComponent {
*/ */
int STATE_DISABLED = 0; int STATE_DISABLED = 0;
/** /**
* The renderer is enabled but not started. A renderer in this state will typically hold any * The renderer is enabled but not started. A renderer in this state is not actively rendering
* resources that it requires for rendering (e.g. media decoders). * media, but will typically hold resources that it requires for rendering (e.g. media decoders).
*/ */
int STATE_ENABLED = 1; int STATE_ENABLED = 1;
/** /**
...@@ -88,7 +87,7 @@ public interface Renderer extends ExoPlayerComponent { ...@@ -88,7 +87,7 @@ public interface Renderer extends ExoPlayerComponent {
int getState(); int getState();
/** /**
* Enable the renderer to consume from the specified {@link SampleStream}. * Enables the renderer to consume from the specified {@link SampleStream}.
* <p> * <p>
* This method may be called when the renderer is in the following states: * This method may be called when the renderer is in the following states:
* {@link #STATE_DISABLED}. * {@link #STATE_DISABLED}.
...@@ -165,7 +164,7 @@ public interface Renderer extends ExoPlayerComponent { ...@@ -165,7 +164,7 @@ public interface Renderer extends ExoPlayerComponent {
void maybeThrowStreamError() throws IOException; void maybeThrowStreamError() throws IOException;
/** /**
* Called when a position discontinuity is encountered. * Signals to the renderer that a position discontinuity has occurred.
* <p> * <p>
* After a position discontinuity, the renderer's {@link SampleStream} is guaranteed to provide * After a position discontinuity, the renderer's {@link SampleStream} is guaranteed to provide
* samples starting from a key frame. * samples starting from a key frame.
...@@ -231,7 +230,7 @@ public interface Renderer extends ExoPlayerComponent { ...@@ -231,7 +230,7 @@ public interface Renderer extends ExoPlayerComponent {
boolean isEnded(); boolean isEnded();
/** /**
* Stops the renderer. * Stops the renderer, transitioning it to the {@link #STATE_ENABLED} state.
* <p> * <p>
* This method may be called when the renderer is in the following states: * This method may be called when the renderer is in the following states:
* {@link #STATE_STARTED}. * {@link #STATE_STARTED}.
...@@ -241,7 +240,7 @@ public interface Renderer extends ExoPlayerComponent { ...@@ -241,7 +240,7 @@ public interface Renderer extends ExoPlayerComponent {
void stop() throws ExoPlaybackException; void stop() throws ExoPlaybackException;
/** /**
* Disable the renderer. * Disable the renderer, transitioning it to the {@link #STATE_DISABLED} state.
* <p> * <p>
* This method may be called when the renderer is in the following states: * This method may be called when the renderer is in the following states:
* {@link #STATE_ENABLED}. * {@link #STATE_ENABLED}.
......
...@@ -33,30 +33,30 @@ public interface RendererCapabilities { ...@@ -33,30 +33,30 @@ public interface RendererCapabilities {
*/ */
int FORMAT_HANDLED = 0b11; int FORMAT_HANDLED = 0b11;
/** /**
* The {@link Renderer} is capable of rendering formats with the same mimeType, but the * The {@link Renderer} is capable of rendering formats with the same mime type, but the
* properties of the format exceed the renderer's capability. * properties of the format exceed the renderer's capability.
* <p> * <p>
* Example: The {@link Renderer} is capable of rendering H264 and the format's mimeType is * Example: The {@link Renderer} is capable of rendering H264 and the format's mime type is
* {@link MimeTypes#VIDEO_H264}, but the format's resolution exceeds the maximum limit supported * {@link MimeTypes#VIDEO_H264}, but the format's resolution exceeds the maximum limit supported
* by the underlying H264 decoder. * by the underlying H264 decoder.
*/ */
int FORMAT_EXCEEDS_CAPABILITIES = 0b10; int FORMAT_EXCEEDS_CAPABILITIES = 0b10;
/** /**
* The {@link Renderer} is a general purpose renderer for formats of the same top-level type, * The {@link Renderer} is a general purpose renderer for formats of the same top-level type,
* but is not capable of rendering the format or any other format with the same mimeType because * but is not capable of rendering the format or any other format with the same mime type because
* the sub-type is not supported. * the sub-type is not supported.
* <p> * <p>
* Example: The {@link Renderer} is a general purpose audio renderer and the format's * Example: The {@link Renderer} is a general purpose audio renderer and the format's
* mimeType matches audio/[subtype], but there does not exist a suitable decoder for [subtype]. * mime type matches audio/[subtype], but there does not exist a suitable decoder for [subtype].
*/ */
int FORMAT_UNSUPPORTED_SUBTYPE = 0b01; int FORMAT_UNSUPPORTED_SUBTYPE = 0b01;
/** /**
* The {@link Renderer} is not capable of rendering the format, either because it does not * The {@link Renderer} is not capable of rendering the format, either because it does not
* support the format's top-level type, or because it's a specialized renderer for a different * support the format's top-level type, or because it's a specialized renderer for a different
* mimeType. * mime type.
* <p> * <p>
* Example: The {@link Renderer} is a general purpose video renderer, but the format has an * Example: The {@link Renderer} is a general purpose video renderer, but the format has an
* audio mimeType. * audio mime type.
*/ */
int FORMAT_UNSUPPORTED_TYPE = 0b00; int FORMAT_UNSUPPORTED_TYPE = 0b00;
...@@ -80,19 +80,23 @@ public interface RendererCapabilities { ...@@ -80,19 +80,23 @@ public interface RendererCapabilities {
int ADAPTIVE_NOT_SUPPORTED = 0b0000; int ADAPTIVE_NOT_SUPPORTED = 0b0000;
/** /**
* Returns the track type that the {@link Renderer} handles. For example, a video renderer will
* return {@link C#TRACK_TYPE_VIDEO}, an audio renderer will return {@link C#TRACK_TYPE_AUDIO}, a
* text renderer will return {@link C#TRACK_TYPE_TEXT}, and so on.
*
* @see Renderer#getTrackType() * @see Renderer#getTrackType()
* @return One of the {@code TRACK_TYPE_*} constants defined in {@link C}.
*/ */
int getTrackType(); int getTrackType();
/** /**
* Returns the extent to which the {@link Renderer} supports a given format. * Returns the extent to which the {@link Renderer} supports a given format. The returned value is
* <p> * the bitwise OR of two properties:
* The returned value is the bitwise OR of two properties:
* <ul> * <ul>
* <li>The level of support for the format itself. One of {@code}link #FORMAT_HANDLED}, * <li>The level of support for the format itself. One of {@link #FORMAT_HANDLED},
* {@link #FORMAT_EXCEEDS_CAPABILITIES}, {@link #FORMAT_UNSUPPORTED_SUBTYPE} and * {@link #FORMAT_EXCEEDS_CAPABILITIES}, {@link #FORMAT_UNSUPPORTED_SUBTYPE} and
* {@link #FORMAT_UNSUPPORTED_TYPE}.</li> * {@link #FORMAT_UNSUPPORTED_TYPE}.</li>
* <li>The level of support for adapting from the format to another format of the same mimeType. * <li>The level of support for adapting from the format to another format of the same mime type.
* One of {@link #ADAPTIVE_SEAMLESS}, {@link #ADAPTIVE_NOT_SEAMLESS} and * One of {@link #ADAPTIVE_SEAMLESS}, {@link #ADAPTIVE_NOT_SEAMLESS} and
* {@link #ADAPTIVE_NOT_SUPPORTED}.</li> * {@link #ADAPTIVE_NOT_SUPPORTED}.</li>
* </ul> * </ul>
...@@ -107,10 +111,10 @@ public interface RendererCapabilities { ...@@ -107,10 +111,10 @@ public interface RendererCapabilities {
/** /**
* Returns the extent to which the {@link Renderer} supports adapting between supported formats * Returns the extent to which the {@link Renderer} supports adapting between supported formats
* that have different mimeTypes. * that have different mime types.
* *
* @return The extent to which the renderer supports adapting between supported formats that have * @return The extent to which the renderer supports adapting between supported formats that have
* different mimeTypes. One of {@link #ADAPTIVE_SEAMLESS}, {@link #ADAPTIVE_NOT_SEAMLESS} and * different mime types. One of {@link #ADAPTIVE_SEAMLESS}, {@link #ADAPTIVE_NOT_SEAMLESS} and
* {@link #ADAPTIVE_NOT_SUPPORTED}. * {@link #ADAPTIVE_NOT_SUPPORTED}.
* @throws ExoPlaybackException If an error occurs. * @throws ExoPlaybackException If an error occurs.
*/ */
......
...@@ -45,39 +45,44 @@ import java.util.ArrayList; ...@@ -45,39 +45,44 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
* An {@link ExoPlayer} that uses default {@link Renderer} components. * An {@link ExoPlayer} that uses default {@link Renderer} components. Instances can be obtained
* <p> * from {@link ExoPlayerFactory}.
* Instances of this class can be obtained from {@link ExoPlayerFactory}.
*/ */
@TargetApi(16) @TargetApi(16)
public final class SimpleExoPlayer implements ExoPlayer { public final class SimpleExoPlayer implements ExoPlayer {
/** /**
* A listener for video rendering information. * A listener for video rendering information from a {@link SimpleExoPlayer}.
*/ */
public interface VideoListener { public interface VideoListener {
/**
* Called each time there's a change in the size of the video being rendered.
*
* @param width The video width in pixels.
* @param height The video height in pixels.
* @param unappliedRotationDegrees For videos that require a rotation, this is the clockwise
* rotation in degrees that the application should apply for the video for it to be rendered
* in the correct orientation. This value will always be zero on API levels 21 and above,
* since the renderer will apply all necessary rotations internally. On earlier API levels
* this is not possible. Applications that use {@link android.view.TextureView} can apply
* the rotation by calling {@link android.view.TextureView#setTransform}. Applications that
* do not expect to encounter rotated videos can safely ignore this parameter.
* @param pixelWidthHeightRatio The width to height ratio of each pixel. For the normal case
* of square pixels this will be equal to 1.0. Different values are indicative of anamorphic
* content.
*/
void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees,
float pixelWidthHeightRatio); float pixelWidthHeightRatio);
/**
* Called when a frame is rendered for the first time since setting the surface, and when a
* frame is rendered for the first time since video was enabled.
*
* @param surface The {@link Surface} to which a first frame has been rendered.
*/
void onRenderedFirstFrame(Surface surface); void onRenderedFirstFrame(Surface surface);
}
/**
* A listener for debugging information.
*/
public interface DebugListener {
void onAudioEnabled(DecoderCounters counters);
void onAudioSessionId(int audioSessionId);
void onAudioDecoderInitialized(String decoderName, long elapsedRealtimeMs,
long initializationDurationMs);
void onAudioFormatChanged(Format format);
void onAudioDisabled(DecoderCounters counters);
void onVideoEnabled(DecoderCounters counters);
void onVideoDecoderInitialized(String decoderName, long elapsedRealtimeMs,
long initializationDurationMs);
void onVideoFormatChanged(Format format);
void onVideoDisabled(DecoderCounters counters);
void onDroppedFrames(int count, long elapsed);
void onAudioTrackUnderrun(int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs);
} }
private static final String TAG = "SimpleExoPlayer"; private static final String TAG = "SimpleExoPlayer";
...@@ -97,7 +102,8 @@ public final class SimpleExoPlayer implements ExoPlayer { ...@@ -97,7 +102,8 @@ public final class SimpleExoPlayer implements ExoPlayer {
private TextRenderer.Output textOutput; private TextRenderer.Output textOutput;
private MetadataRenderer.Output<List<Id3Frame>> id3Output; private MetadataRenderer.Output<List<Id3Frame>> id3Output;
private VideoListener videoListener; private VideoListener videoListener;
private DebugListener debugListener; private AudioRendererEventListener audioDebugListener;
private VideoRendererEventListener videoDebugListener;
private DecoderCounters videoDecoderCounters; private DecoderCounters videoDecoderCounters;
private DecoderCounters audioDecoderCounters; private DecoderCounters audioDecoderCounters;
private int audioSessionId; private int audioSessionId;
...@@ -308,12 +314,21 @@ public final class SimpleExoPlayer implements ExoPlayer { ...@@ -308,12 +314,21 @@ public final class SimpleExoPlayer implements ExoPlayer {
} }
/** /**
* Sets a listener to receive debug events. * Sets a listener to receive debug events from the video renderer.
*
* @param listener The listener.
*/
public void setVideoDebugListener(VideoRendererEventListener listener) {
videoDebugListener = listener;
}
/**
* Sets a listener to receive debug events from the audio renderer.
* *
* @param listener The listener. * @param listener The listener.
*/ */
public void setDebugListener(DebugListener listener) { public void setAudioDebugListener(AudioRendererEventListener listener) {
debugListener = listener; audioDebugListener = listener;
} }
/** /**
...@@ -606,16 +621,16 @@ public final class SimpleExoPlayer implements ExoPlayer { ...@@ -606,16 +621,16 @@ public final class SimpleExoPlayer implements ExoPlayer {
@Override @Override
public void onVideoEnabled(DecoderCounters counters) { public void onVideoEnabled(DecoderCounters counters) {
videoDecoderCounters = counters; videoDecoderCounters = counters;
if (debugListener != null) { if (videoDebugListener != null) {
debugListener.onVideoEnabled(counters); videoDebugListener.onVideoEnabled(counters);
} }
} }
@Override @Override
public void onVideoDecoderInitialized(String decoderName, long initializedTimestampMs, public void onVideoDecoderInitialized(String decoderName, long initializedTimestampMs,
long initializationDurationMs) { long initializationDurationMs) {
if (debugListener != null) { if (videoDebugListener != null) {
debugListener.onVideoDecoderInitialized(decoderName, initializedTimestampMs, videoDebugListener.onVideoDecoderInitialized(decoderName, initializedTimestampMs,
initializationDurationMs); initializationDurationMs);
} }
} }
...@@ -623,15 +638,15 @@ public final class SimpleExoPlayer implements ExoPlayer { ...@@ -623,15 +638,15 @@ public final class SimpleExoPlayer implements ExoPlayer {
@Override @Override
public void onVideoInputFormatChanged(Format format) { public void onVideoInputFormatChanged(Format format) {
videoFormat = format; videoFormat = format;
if (debugListener != null) { if (videoDebugListener != null) {
debugListener.onVideoFormatChanged(format); videoDebugListener.onVideoInputFormatChanged(format);
} }
} }
@Override @Override
public void onDroppedFrames(int count, long elapsed) { public void onDroppedFrames(int count, long elapsed) {
if (debugListener != null) { if (videoDebugListener != null) {
debugListener.onDroppedFrames(count, elapsed); videoDebugListener.onDroppedFrames(count, elapsed);
} }
} }
...@@ -642,6 +657,10 @@ public final class SimpleExoPlayer implements ExoPlayer { ...@@ -642,6 +657,10 @@ public final class SimpleExoPlayer implements ExoPlayer {
videoListener.onVideoSizeChanged(width, height, unappliedRotationDegrees, videoListener.onVideoSizeChanged(width, height, unappliedRotationDegrees,
pixelWidthHeightRatio); pixelWidthHeightRatio);
} }
if (videoDebugListener != null) {
videoDebugListener.onVideoSizeChanged(width, height, unappliedRotationDegrees,
pixelWidthHeightRatio);
}
} }
@Override @Override
...@@ -649,12 +668,15 @@ public final class SimpleExoPlayer implements ExoPlayer { ...@@ -649,12 +668,15 @@ public final class SimpleExoPlayer implements ExoPlayer {
if (videoListener != null) { if (videoListener != null) {
videoListener.onRenderedFirstFrame(surface); videoListener.onRenderedFirstFrame(surface);
} }
if (videoDebugListener != null) {
videoDebugListener.onRenderedFirstFrame(surface);
}
} }
@Override @Override
public void onVideoDisabled(DecoderCounters counters) { public void onVideoDisabled(DecoderCounters counters) {
if (debugListener != null) { if (videoDebugListener != null) {
debugListener.onVideoDisabled(counters); videoDebugListener.onVideoDisabled(counters);
} }
videoFormat = null; videoFormat = null;
videoDecoderCounters = null; videoDecoderCounters = null;
...@@ -665,24 +687,24 @@ public final class SimpleExoPlayer implements ExoPlayer { ...@@ -665,24 +687,24 @@ public final class SimpleExoPlayer implements ExoPlayer {
@Override @Override
public void onAudioEnabled(DecoderCounters counters) { public void onAudioEnabled(DecoderCounters counters) {
audioDecoderCounters = counters; audioDecoderCounters = counters;
if (debugListener != null) { if (audioDebugListener != null) {
debugListener.onAudioEnabled(counters); audioDebugListener.onAudioEnabled(counters);
} }
} }
@Override @Override
public void onAudioSessionId(int sessionId) { public void onAudioSessionId(int sessionId) {
audioSessionId = sessionId; audioSessionId = sessionId;
if (debugListener != null) { if (audioDebugListener != null) {
debugListener.onAudioSessionId(sessionId); audioDebugListener.onAudioSessionId(sessionId);
} }
} }
@Override @Override
public void onAudioDecoderInitialized(String decoderName, long initializedTimestampMs, public void onAudioDecoderInitialized(String decoderName, long initializedTimestampMs,
long initializationDurationMs) { long initializationDurationMs) {
if (debugListener != null) { if (audioDebugListener != null) {
debugListener.onAudioDecoderInitialized(decoderName, initializedTimestampMs, audioDebugListener.onAudioDecoderInitialized(decoderName, initializedTimestampMs,
initializationDurationMs); initializationDurationMs);
} }
} }
...@@ -690,23 +712,23 @@ public final class SimpleExoPlayer implements ExoPlayer { ...@@ -690,23 +712,23 @@ public final class SimpleExoPlayer implements ExoPlayer {
@Override @Override
public void onAudioInputFormatChanged(Format format) { public void onAudioInputFormatChanged(Format format) {
audioFormat = format; audioFormat = format;
if (debugListener != null) { if (audioDebugListener != null) {
debugListener.onAudioFormatChanged(format); audioDebugListener.onAudioInputFormatChanged(format);
} }
} }
@Override @Override
public void onAudioTrackUnderrun(int bufferSize, long bufferSizeMs, public void onAudioTrackUnderrun(int bufferSize, long bufferSizeMs,
long elapsedSinceLastFeedMs) { long elapsedSinceLastFeedMs) {
if (debugListener != null) { if (audioDebugListener != null) {
debugListener.onAudioTrackUnderrun(bufferSize, bufferSizeMs, elapsedSinceLastFeedMs); audioDebugListener.onAudioTrackUnderrun(bufferSize, bufferSizeMs, elapsedSinceLastFeedMs);
} }
} }
@Override @Override
public void onAudioDisabled(DecoderCounters counters) { public void onAudioDisabled(DecoderCounters counters) {
if (debugListener != null) { if (audioDebugListener != null) {
debugListener.onAudioDisabled(counters); audioDebugListener.onAudioDisabled(counters);
} }
audioFormat = null; audioFormat = null;
audioDecoderCounters = null; audioDecoderCounters = null;
......
...@@ -178,7 +178,8 @@ public final class AudioTrack { ...@@ -178,7 +178,8 @@ public final class AudioTrack {
/** /**
* Whether to enable a workaround for an issue where an audio effect does not keep its session * Whether to enable a workaround for an issue where an audio effect does not keep its session
* active across releasing/initializing a new audio track, on platform API version &lt; 21. * active across releasing/initializing a new audio track, on platform builds where
* {@link Util#SDK_INT} &lt; 21.
* <p> * <p>
* The flag must be set before creating a player. * The flag must be set before creating a player.
*/ */
...@@ -267,8 +268,10 @@ public final class AudioTrack { ...@@ -267,8 +268,10 @@ public final class AudioTrack {
} }
/** /**
* Returns whether it is possible to play back input audio in the specified format using encoded * Returns whether it's possible to play audio in the specified format using encoded passthrough.
* audio passthrough. *
* @param mimeType The format mime type.
* @return Whether it's possible to play audio in the format using encoded passthrough.
*/ */
public boolean isPassthroughSupported(String mimeType) { public boolean isPassthroughSupported(String mimeType) {
return audioCapabilities != null return audioCapabilities != null
...@@ -679,13 +682,15 @@ public final class AudioTrack { ...@@ -679,13 +682,15 @@ public final class AudioTrack {
} }
/** /**
* Sets the playback parameters. Only available for SDK_INT &gt;= 23 * Sets the playback parameters. Only available for {@link Util#SDK_INT} &gt;= 23
* *
* @param playbackParams The playback parameters to be used by the
* {@link android.media.AudioTrack}.
* @throws UnsupportedOperationException if the Playback Parameters are not supported. That is, * @throws UnsupportedOperationException if the Playback Parameters are not supported. That is,
* SDK_INT &lt; 23. * {@link Util#SDK_INT} &lt; 23.
*/ */
public void setPlaybackParams(PlaybackParams playbackParams) { public void setPlaybackParams(PlaybackParams playbackParams) {
audioTrackUtil.setPlaybackParameters(playbackParams); audioTrackUtil.setPlaybackParams(playbackParams);
} }
/** /**
...@@ -1214,11 +1219,12 @@ public final class AudioTrack { ...@@ -1214,11 +1219,12 @@ public final class AudioTrack {
/** /**
* Sets the Playback Parameters to be used by the underlying {@link android.media.AudioTrack}. * Sets the Playback Parameters to be used by the underlying {@link android.media.AudioTrack}.
* *
* @param playbackParams to be used by the {@link android.media.AudioTrack}. * @param playbackParams The playback parameters to be used by the
* {@link android.media.AudioTrack}.
* @throws UnsupportedOperationException If Playback Parameters are not supported * @throws UnsupportedOperationException If Playback Parameters are not supported
* (i.e. SDK_INT &lt; 23). * (i.e. {@link Util#SDK_INT} &lt; 23).
*/ */
public void setPlaybackParameters(PlaybackParams playbackParams) { public void setPlaybackParams(PlaybackParams playbackParams) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
...@@ -1301,7 +1307,7 @@ public final class AudioTrack { ...@@ -1301,7 +1307,7 @@ public final class AudioTrack {
} }
@Override @Override
public void setPlaybackParameters(PlaybackParams playbackParams) { public void setPlaybackParams(PlaybackParams playbackParams) {
playbackParams = (playbackParams != null ? playbackParams : new PlaybackParams()) playbackParams = (playbackParams != null ? playbackParams : new PlaybackParams())
.allowDefaults(); .allowDefaults();
this.playbackParams = playbackParams; this.playbackParams = playbackParams;
......
...@@ -19,7 +19,7 @@ import android.annotation.TargetApi; ...@@ -19,7 +19,7 @@ import android.annotation.TargetApi;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
/** /**
* Compatibility wrapper around {@link android.media.MediaCodec.CryptoInfo}. * Compatibility wrapper for {@link android.media.MediaCodec.CryptoInfo}.
*/ */
public final class CryptoInfo { public final class CryptoInfo {
......
...@@ -56,9 +56,8 @@ public interface Decoder<I, O, E extends Exception> { ...@@ -56,9 +56,8 @@ public interface Decoder<I, O, E extends Exception> {
O dequeueOutputBuffer() throws E; O dequeueOutputBuffer() throws E;
/** /**
* Flushes input/output buffers that have not been dequeued yet and returns ownership of any * Flushes the decoder. Ownership of dequeued input buffers is returned to the decoder. The caller
* dequeued input buffer to the decoder. Flushes any pending output currently in the decoder. The * is still responsible for releasing any dequeued output buffers.
* caller is still responsible for releasing any dequeued output buffers.
*/ */
void flush(); void flush();
......
...@@ -19,7 +19,7 @@ import com.google.android.exoplayer2.C; ...@@ -19,7 +19,7 @@ import com.google.android.exoplayer2.C;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
/** /**
* Holds input for a decoder and corresponding metadata. * Holds input for a decoder.
*/ */
public class DecoderInputBuffer extends Buffer { public class DecoderInputBuffer extends Buffer {
......
...@@ -27,7 +27,7 @@ import java.util.List; ...@@ -27,7 +27,7 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
/** /**
* Encapsulates DRM initialization data for possibly multiple DRM schemes. * Initialization data for one or more DRM schemes.
*/ */
public final class DrmInitData implements Comparator<SchemeData>, Parcelable { public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
......
...@@ -25,7 +25,7 @@ import android.media.MediaCrypto; ...@@ -25,7 +25,7 @@ import android.media.MediaCrypto;
public interface DrmSession { public interface DrmSession {
/** /**
* The session is in an error state. {@link #getError()} can be used to retrieve the cause. * The session has encountered an error. {@link #getError()} can be used to retrieve the cause.
*/ */
int STATE_ERROR = 0; int STATE_ERROR = 0;
/** /**
...@@ -56,7 +56,7 @@ public interface DrmSession { ...@@ -56,7 +56,7 @@ public interface DrmSession {
/** /**
* Returns a {@link MediaCrypto} for the open session. * Returns a {@link MediaCrypto} for the open session.
* <p> * <p>
* This method may be called when the manager is in the following states: * This method may be called when the session is in the following states:
* {@link #STATE_OPENED}, {@link #STATE_OPENED_WITH_KEYS} * {@link #STATE_OPENED}, {@link #STATE_OPENED_WITH_KEYS}
* *
* @return A {@link MediaCrypto} for the open session. * @return A {@link MediaCrypto} for the open session.
...@@ -71,7 +71,7 @@ public interface DrmSession { ...@@ -71,7 +71,7 @@ public interface DrmSession {
* however in some cases implementations may wish to modify the return value (i.e. to force a * however in some cases implementations may wish to modify the return value (i.e. to force a
* secure decoder even when one is not required). * secure decoder even when one is not required).
* <p> * <p>
* This method may be called when the manager is in the following states: * This method may be called when the session is in the following states:
* {@link #STATE_OPENED}, {@link #STATE_OPENED_WITH_KEYS} * {@link #STATE_OPENED}, {@link #STATE_OPENED_WITH_KEYS}
* *
* @return Whether the open session requires a secure decoder for the specified mime type. * @return Whether the open session requires a secure decoder for the specified mime type.
...@@ -82,7 +82,7 @@ public interface DrmSession { ...@@ -82,7 +82,7 @@ public interface DrmSession {
/** /**
* Returns the cause of the error state. * Returns the cause of the error state.
* <p> * <p>
* This method may be called when the manager is in any state. * This method may be called when the session is in any state.
* *
* @return An exception if the state is {@link #STATE_ERROR}. Null otherwise. * @return An exception if the state is {@link #STATE_ERROR}. Null otherwise.
*/ */
......
...@@ -25,10 +25,8 @@ import android.os.Looper; ...@@ -25,10 +25,8 @@ import android.os.Looper;
public interface DrmSessionManager { public interface DrmSessionManager {
/** /**
* Acquires a {@link DrmSession} for the specified {@link DrmInitData}. * Acquires a {@link DrmSession} for the specified {@link DrmInitData}. The {@link DrmSession}
* <p> * must be returned to {@link #releaseSession(DrmSession)} when it is no longer required.
* The {@link DrmSession} must be returned to {@link #releaseSession(DrmSession)} when it is no
* longer required
* *
* @param playbackLooper The looper associated with the media playback thread. * @param playbackLooper The looper associated with the media playback thread.
* @param drmInitData DRM initialization data. * @param drmInitData DRM initialization data.
......
...@@ -31,7 +31,7 @@ public final class UnsupportedDrmException extends Exception { ...@@ -31,7 +31,7 @@ public final class UnsupportedDrmException extends Exception {
public static final int REASON_INSTANTIATION_ERROR = 2; public static final int REASON_INSTANTIATION_ERROR = 2;
/** /**
* {@link #REASON_UNSUPPORTED_SCHEME} or {@link #REASON_INSTANTIATION_ERROR}. * Either {@link #REASON_UNSUPPORTED_SCHEME} or {@link #REASON_INSTANTIATION_ERROR}.
*/ */
public final int reason; public final int reason;
......
...@@ -19,7 +19,7 @@ import com.google.android.exoplayer2.C; ...@@ -19,7 +19,7 @@ import com.google.android.exoplayer2.C;
import java.io.IOException; import java.io.IOException;
/** /**
* Facilitates extraction of data from a container format. * Extracts media data from a container format.
*/ */
public interface Extractor { public interface Extractor {
......
...@@ -31,7 +31,7 @@ import java.io.IOException; ...@@ -31,7 +31,7 @@ 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}. * Factory for {@link FlvExtractor} instances.
*/ */
public static final ExtractorsFactory FACTORY = new ExtractorsFactory() { public static final ExtractorsFactory FACTORY = new ExtractorsFactory() {
......
...@@ -52,7 +52,7 @@ import java.util.UUID; ...@@ -52,7 +52,7 @@ 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}. * Factory for {@link MatroskaExtractor} instances.
*/ */
public static final ExtractorsFactory FACTORY = new ExtractorsFactory() { public static final ExtractorsFactory FACTORY = new ExtractorsFactory() {
......
...@@ -38,7 +38,7 @@ import java.io.IOException; ...@@ -38,7 +38,7 @@ 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}. * Factory for {@link Mp3Extractor} instances.
*/ */
public static final ExtractorsFactory FACTORY = new ExtractorsFactory() { public static final ExtractorsFactory FACTORY = new ExtractorsFactory() {
......
...@@ -50,7 +50,7 @@ import java.util.UUID; ...@@ -50,7 +50,7 @@ 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}. * Factory for {@link FragmentedMp4Extractor} instances.
*/ */
public static final ExtractorsFactory FACTORY = new ExtractorsFactory() { public static final ExtractorsFactory FACTORY = new ExtractorsFactory() {
......
...@@ -42,7 +42,7 @@ import java.util.Stack; ...@@ -42,7 +42,7 @@ 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}. * Factory for {@link Mp4Extractor} instances.
*/ */
public static final ExtractorsFactory FACTORY = new ExtractorsFactory() { public static final ExtractorsFactory FACTORY = new ExtractorsFactory() {
......
...@@ -31,7 +31,7 @@ import java.io.IOException; ...@@ -31,7 +31,7 @@ import java.io.IOException;
public class OggExtractor implements Extractor { public class OggExtractor implements Extractor {
/** /**
* Factory that returns one extractor which is an {@link OggExtractor}. * Factory for {@link OggExtractor} instances.
*/ */
public static final ExtractorsFactory FACTORY = new ExtractorsFactory() { public static final ExtractorsFactory FACTORY = new ExtractorsFactory() {
......
...@@ -34,7 +34,7 @@ import java.io.IOException; ...@@ -34,7 +34,7 @@ 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}. * Factory for {@link AdtsExtractor} instances.
*/ */
public static final ExtractorsFactory FACTORY = new ExtractorsFactory() { public static final ExtractorsFactory FACTORY = new ExtractorsFactory() {
......
...@@ -33,7 +33,7 @@ import java.io.IOException; ...@@ -33,7 +33,7 @@ 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}. * Factory for {@link PsExtractor} instances.
*/ */
public static final ExtractorsFactory FACTORY = new ExtractorsFactory() { public static final ExtractorsFactory FACTORY = new ExtractorsFactory() {
......
...@@ -38,7 +38,7 @@ import java.io.IOException; ...@@ -38,7 +38,7 @@ 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}. * Factory for {@link TsExtractor} instances.
*/ */
public static final ExtractorsFactory FACTORY = new ExtractorsFactory() { public static final ExtractorsFactory FACTORY = new ExtractorsFactory() {
......
...@@ -32,7 +32,7 @@ import java.io.IOException; ...@@ -32,7 +32,7 @@ import java.io.IOException;
public final class WavExtractor implements Extractor, SeekMap { public final class WavExtractor implements Extractor, SeekMap {
/** /**
* Factory that returns one extractor which is a {@link WavExtractor}. * Factory for {@link WavExtractor} instances.
*/ */
public static final ExtractorsFactory FACTORY = new ExtractorsFactory() { public static final ExtractorsFactory FACTORY = new ExtractorsFactory() {
......
...@@ -27,7 +27,7 @@ import com.google.android.exoplayer2.util.MimeTypes; ...@@ -27,7 +27,7 @@ import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
/** /**
* Contains information about a {@link MediaCodec} decoder. * Information about a {@link MediaCodec} for a given mime type.
*/ */
@TargetApi(16) @TargetApi(16)
public final class MediaCodecInfo { public final class MediaCodecInfo {
...@@ -51,10 +51,24 @@ public final class MediaCodecInfo { ...@@ -51,10 +51,24 @@ public final class MediaCodecInfo {
private final String mimeType; private final String mimeType;
private final CodecCapabilities capabilities; private final CodecCapabilities capabilities;
/**
* Creates an instance representing an audio passthrough decoder.
*
* @param name The name of the {@link MediaCodec}.
* @return The created instance.
*/
public static MediaCodecInfo newPassthroughInstance(String name) { public static MediaCodecInfo newPassthroughInstance(String name) {
return new MediaCodecInfo(name, null, null); return new MediaCodecInfo(name, null, null);
} }
/**
* Creates an instance.
*
* @param name The name of the {@link MediaCodec}.
* @param mimeType A mime type supported by the {@link MediaCodec}.
* @param capabilities The capabilities of the {@link MediaCodec} for the specified mime type.
* @return The created instance.
*/
public static MediaCodecInfo newInstance(String name, String mimeType, public static MediaCodecInfo newInstance(String name, String mimeType,
CodecCapabilities capabilities) { CodecCapabilities capabilities) {
return new MediaCodecInfo(name, mimeType, capabilities); return new MediaCodecInfo(name, mimeType, capabilities);
......
...@@ -106,6 +106,7 @@ public final class MediaCodecUtil { ...@@ -106,6 +106,7 @@ public final class MediaCodecUtil {
* unless secure decryption really is required. * unless secure decryption really is required.
* @return A {@link MediaCodecInfo} describing the decoder, or null if no suitable decoder * @return A {@link MediaCodecInfo} describing the decoder, or null if no suitable decoder
* exists. * exists.
* @throws DecoderQueryException If there was an error querying the available decoders.
*/ */
public static MediaCodecInfo getDecoderInfo(String mimeType, boolean secure) public static MediaCodecInfo getDecoderInfo(String mimeType, boolean secure)
throws DecoderQueryException { throws DecoderQueryException {
...@@ -122,6 +123,7 @@ public final class MediaCodecUtil { ...@@ -122,6 +123,7 @@ public final class MediaCodecUtil {
* unless secure decryption really is required. * unless secure decryption really is required.
* @return A list of all @{link MediaCodecInfo}s for the given mime type, in the order * @return A list of all @{link MediaCodecInfo}s for the given mime type, in the order
* given by {@link MediaCodecList}. * given by {@link MediaCodecList}.
* @throws DecoderQueryException If there was an error querying the available decoders.
*/ */
public static synchronized List<MediaCodecInfo> getDecoderInfos(String mimeType, public static synchronized List<MediaCodecInfo> getDecoderInfos(String mimeType,
boolean secure) throws DecoderQueryException { boolean secure) throws DecoderQueryException {
......
...@@ -31,11 +31,11 @@ public interface MetadataDecoder<T> { ...@@ -31,11 +31,11 @@ public interface MetadataDecoder<T> {
boolean canDecode(String mimeType); boolean canDecode(String mimeType);
/** /**
* Decodes metadata object from the provided binary data. * Decodes a metadata object from the provided binary data.
* *
* @param data The raw binary data from which to decode the metadata. * @param data The raw binary data from which to decode the metadata.
* @param size The size of the input data. * @param size The size of the input data.
* @return @return A decoded metadata object. * @return The decoded metadata object.
* @throws MetadataDecoderException If a problem occurred decoding the data. * @throws MetadataDecoderException If a problem occurred decoding the data.
*/ */
T decode(byte[] data, int size) throws MetadataDecoderException; T decode(byte[] data, int size) throws MetadataDecoderException;
......
...@@ -36,7 +36,7 @@ import java.nio.ByteBuffer; ...@@ -36,7 +36,7 @@ import java.nio.ByteBuffer;
public final class MetadataRenderer<T> extends BaseRenderer implements Callback { public final class MetadataRenderer<T> extends BaseRenderer implements Callback {
/** /**
* An output for the renderer. * Receives output from a {@link MetadataRenderer}.
* *
* @param <T> The type of the metadata. * @param <T> The type of the metadata.
*/ */
...@@ -45,7 +45,7 @@ public final class MetadataRenderer<T> extends BaseRenderer implements Callback ...@@ -45,7 +45,7 @@ public final class MetadataRenderer<T> extends BaseRenderer implements Callback
/** /**
* Called each time there is a metadata associated with current playback time. * Called each time there is a metadata associated with current playback time.
* *
* @param metadata The metadata to process. * @param metadata The metadata.
*/ */
void onMetadata(T metadata); void onMetadata(T metadata);
......
...@@ -314,13 +314,14 @@ public class DashManifestParser extends DefaultHandler ...@@ -314,13 +314,14 @@ public class DashManifestParser extends DefaultHandler
/** /**
* Parses a ContentProtection element. * Parses a ContentProtection element.
* *
* @param xpp The parser from which to read.
* @throws XmlPullParserException If an error occurs parsing the element. * @throws XmlPullParserException If an error occurs parsing the element.
* @throws IOException If an error occurs reading the element. * @throws IOException If an error occurs reading the element.
* @return {@link SchemeData} parsed from the ContentProtection element, or null if the element is * @return {@link SchemeData} parsed from the ContentProtection element, or null if the element is
* unsupported. * unsupported.
**/ */
protected SchemeData parseContentProtection(XmlPullParser xpp) protected SchemeData parseContentProtection(XmlPullParser xpp) throws XmlPullParserException,
throws XmlPullParserException, IOException { IOException {
byte[] data = null; byte[] data = null;
UUID uuid = null; UUID uuid = null;
boolean seenPsshElement = false; boolean seenPsshElement = false;
...@@ -353,7 +354,7 @@ public class DashManifestParser extends DefaultHandler ...@@ -353,7 +354,7 @@ public class DashManifestParser extends DefaultHandler
* @param xpp The XmpPullParser from which the AdaptationSet child should be parsed. * @param xpp The XmpPullParser from which the AdaptationSet child should be parsed.
* @throws XmlPullParserException If an error occurs parsing the element. * @throws XmlPullParserException If an error occurs parsing the element.
* @throws IOException If an error occurs reading the element. * @throws IOException If an error occurs reading the element.
**/ */
protected void parseAdaptationSetChild(XmlPullParser xpp) protected void parseAdaptationSetChild(XmlPullParser xpp)
throws XmlPullParserException, IOException { throws XmlPullParserException, IOException {
// pass // pass
......
...@@ -19,7 +19,7 @@ import com.google.android.exoplayer2.C; ...@@ -19,7 +19,7 @@ import com.google.android.exoplayer2.C;
import java.util.List; import java.util.List;
/** /**
* A subtitle that contains textual data associated with time indices. * A subtitle consisting of timed {@link Cue}s.
*/ */
public interface Subtitle { public interface Subtitle {
...@@ -49,7 +49,7 @@ public interface Subtitle { ...@@ -49,7 +49,7 @@ public interface Subtitle {
long getEventTime(int index); long getEventTime(int index);
/** /**
* Retrieve the subtitle cues that should be displayed at a given time. * Retrieve the cues that should be displayed at a given time.
* *
* @param timeUs The time in microseconds. * @param timeUs The time in microseconds.
* @return A list of cues that should be displayed, possibly empty. * @return A list of cues that should be displayed, possibly empty.
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
package com.google.android.exoplayer2.text; package com.google.android.exoplayer2.text;
/** /**
* Thrown when an error occurs decoding text data. * Thrown when an error occurs decoding subtitle data.
*/ */
public class SubtitleDecoderException extends Exception { public class SubtitleDecoderException extends Exception {
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
package com.google.android.exoplayer2.text; package com.google.android.exoplayer2.text;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.decoder.Decoder;
import com.google.android.exoplayer2.text.eia608.Eia608Decoder; import com.google.android.exoplayer2.text.eia608.Eia608Decoder;
import com.google.android.exoplayer2.text.subrip.SubripDecoder; import com.google.android.exoplayer2.text.subrip.SubripDecoder;
import com.google.android.exoplayer2.text.ttml.TtmlDecoder; import com.google.android.exoplayer2.text.ttml.TtmlDecoder;
...@@ -26,7 +25,7 @@ import com.google.android.exoplayer2.text.webvtt.WebvttDecoder; ...@@ -26,7 +25,7 @@ import com.google.android.exoplayer2.text.webvtt.WebvttDecoder;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
/** /**
* A factory for {@link Decoder} instances that will decode subtitles. * A factory for {@link SubtitleDecoder} instances.
*/ */
public interface SubtitleDecoderFactory { public interface SubtitleDecoderFactory {
......
...@@ -39,7 +39,7 @@ import java.util.List; ...@@ -39,7 +39,7 @@ import java.util.List;
public final class TextRenderer extends BaseRenderer implements Callback { public final class TextRenderer extends BaseRenderer implements Callback {
/** /**
* An output for the renderer. * Receives output from a {@link TextRenderer}.
*/ */
public interface Output { public interface Output {
......
...@@ -37,9 +37,8 @@ import org.xmlpull.v1.XmlPullParserException; ...@@ -37,9 +37,8 @@ import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory; import org.xmlpull.v1.XmlPullParserFactory;
/** /**
* A {@link SimpleSubtitleDecoder} for TTML supporting the DFXP presentation profile. * A {@link SimpleSubtitleDecoder} for TTML supporting the DFXP presentation profile. Features
* <p> * supported by this decoder are:
* Supported features in this parser are:
* <ul> * <ul>
* <li>content * <li>content
* <li>core * <li>core
......
...@@ -18,11 +18,11 @@ package com.google.android.exoplayer2.trackselection; ...@@ -18,11 +18,11 @@ package com.google.android.exoplayer2.trackselection;
import android.os.SystemClock; import android.os.SystemClock;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.Format.DecreasingBandwidthComparator;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.chunk.MediaChunk; import com.google.android.exoplayer2.source.chunk.MediaChunk;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator;
import java.util.List; import java.util.List;
/** /**
...@@ -179,4 +179,16 @@ public abstract class BaseTrackSelection implements TrackSelection { ...@@ -179,4 +179,16 @@ public abstract class BaseTrackSelection implements TrackSelection {
return group == other.group && Arrays.equals(tracks, other.tracks); return group == other.group && Arrays.equals(tracks, other.tracks);
} }
/**
* Sorts {@link Format} objects in order of decreasing bandwidth.
*/
private static final class DecreasingBandwidthComparator implements Comparator<Format> {
@Override
public int compare(Format a, Format b) {
return b.bitrate - a.bitrate;
}
}
} }
...@@ -55,7 +55,7 @@ public final class DebugTextViewHelper implements Runnable, ExoPlayer.EventListe ...@@ -55,7 +55,7 @@ public final class DebugTextViewHelper implements Runnable, ExoPlayer.EventListe
} }
started = true; started = true;
player.addListener(this); player.addListener(this);
run(); updateAndPost();
} }
/** /**
...@@ -71,20 +71,52 @@ public final class DebugTextViewHelper implements Runnable, ExoPlayer.EventListe ...@@ -71,20 +71,52 @@ public final class DebugTextViewHelper implements Runnable, ExoPlayer.EventListe
textView.removeCallbacks(this); textView.removeCallbacks(this);
} }
// ExoPlayer.EventListener implementation.
@Override
public void onLoadingChanged(boolean isLoading) {
// Do nothing.
}
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
updateAndPost();
}
@Override
public void onPositionDiscontinuity(int periodIndex, long positionMs) {
updateAndPost();
}
@Override
public void onSourceInfoRefreshed(Timeline timeline, Object manifest) {
// Do nothing.
}
@Override
public void onPlayerError(ExoPlaybackException error) {
// Do nothing.
}
// Runnable implementation.
@Override @Override
public void run() { public void run() {
updateTextView(); updateAndPost();
textView.postDelayed(this, REFRESH_INTERVAL_MS);
} }
private void updateTextView() { // Private methods.
private void updateAndPost() {
textView.setText(getPlayerStateString() + getPlayerWindowIndexString() + getVideoString() textView.setText(getPlayerStateString() + getPlayerWindowIndexString() + getVideoString()
+ getAudioString()); + getAudioString());
textView.removeCallbacks(this);
textView.postDelayed(this, REFRESH_INTERVAL_MS);
} }
private String getPlayerStateString() { private String getPlayerStateString() {
String text = "playWhenReady:" + player.getPlayWhenReady() + " playbackState:"; String text = "playWhenReady:" + player.getPlayWhenReady() + " playbackState:";
switch(player.getPlaybackState()) { switch (player.getPlaybackState()) {
case ExoPlayer.STATE_BUFFERING: case ExoPlayer.STATE_BUFFERING:
text += "buffering"; text += "buffering";
break; break;
...@@ -139,31 +171,4 @@ public final class DebugTextViewHelper implements Runnable, ExoPlayer.EventListe ...@@ -139,31 +171,4 @@ public final class DebugTextViewHelper implements Runnable, ExoPlayer.EventListe
+ " mcdb:" + counters.maxConsecutiveDroppedOutputBufferCount; + " mcdb:" + counters.maxConsecutiveDroppedOutputBufferCount;
} }
// ExoPlayer.EventListener implementation
@Override
public void onLoadingChanged(boolean isLoading) {
// Do nothing.
}
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
updateTextView();
}
@Override
public void onPositionDiscontinuity(int periodIndex, long positionMs) {
updateTextView();
}
@Override
public void onSourceInfoRefreshed(Timeline timeline, Object manifest) {
// Do nothing.
}
@Override
public void onPlayerError(ExoPlaybackException error) {
// Do nothing.
}
} }
...@@ -24,8 +24,8 @@ import com.google.android.exoplayer2.Timeline; ...@@ -24,8 +24,8 @@ import com.google.android.exoplayer2.Timeline;
/** /**
* An {@link OnClickListener} that can be passed to * An {@link OnClickListener} that can be passed to
* {@link android.widget.MediaController#setPrevNextListeners(OnClickListener, OnClickListener)} to * {@link android.widget.MediaController#setPrevNextListeners(OnClickListener, OnClickListener)} to
* make the controller's "previous" and "next" buttons visible and seek to the previous and next * make the controller's previous and next buttons seek to the previous and next windows in the
* windows in the timeline of the media being played. * {@link Timeline}.
*/ */
public class MediaControllerPrevNextClickListener implements OnClickListener { public class MediaControllerPrevNextClickListener implements OnClickListener {
......
...@@ -22,16 +22,18 @@ import com.google.android.exoplayer2.audio.MediaCodecAudioRenderer; ...@@ -22,16 +22,18 @@ import com.google.android.exoplayer2.audio.MediaCodecAudioRenderer;
/** /**
* An implementation of {@link MediaPlayerControl} for controlling an {@link ExoPlayer} instance. * An implementation of {@link MediaPlayerControl} for controlling an {@link ExoPlayer} instance.
* <p>
* This class is provided for convenience, however it is expected that most applications will * This class is provided for convenience, however it is expected that most applications will
* implement their own player controls and therefore not require this class. * implement their own player controls and therefore not require this class.
*/ */
public class PlayerControl implements MediaPlayerControl { public class PlayerControl implements MediaPlayerControl {
private final ExoPlayer exoPlayer; private final ExoPlayer player;
public PlayerControl(ExoPlayer exoPlayer) { /**
this.exoPlayer = exoPlayer; * @param player The player to control.
*/
public PlayerControl(ExoPlayer player) {
this.player = player;
} }
@Override @Override
...@@ -65,39 +67,39 @@ public class PlayerControl implements MediaPlayerControl { ...@@ -65,39 +67,39 @@ public class PlayerControl implements MediaPlayerControl {
@Override @Override
public int getBufferPercentage() { public int getBufferPercentage() {
return exoPlayer.getBufferedPercentage(); return player.getBufferedPercentage();
} }
@Override @Override
public int getCurrentPosition() { public int getCurrentPosition() {
long position = exoPlayer.getCurrentPosition(); long position = player.getCurrentPosition();
return position == C.TIME_UNSET ? 0 : (int) position; return position == C.TIME_UNSET ? 0 : (int) position;
} }
@Override @Override
public int getDuration() { public int getDuration() {
long duration = exoPlayer.getDuration(); long duration = player.getDuration();
return duration == C.TIME_UNSET ? 0 : (int) duration; return duration == C.TIME_UNSET ? 0 : (int) duration;
} }
@Override @Override
public boolean isPlaying() { public boolean isPlaying() {
return exoPlayer.getPlayWhenReady(); return player.getPlayWhenReady();
} }
@Override @Override
public void start() { public void start() {
exoPlayer.setPlayWhenReady(true); player.setPlayWhenReady(true);
} }
@Override @Override
public void pause() { public void pause() {
exoPlayer.setPlayWhenReady(false); player.setPlayWhenReady(false);
} }
@Override @Override
public void seekTo(int timeMillis) { public void seekTo(int timeMillis) {
exoPlayer.seekTo(timeMillis); player.seekTo(timeMillis);
} }
} }
...@@ -148,6 +148,7 @@ public final class Loader implements LoaderErrorThrower { ...@@ -148,6 +148,7 @@ public final class Loader implements LoaderErrorThrower {
* The calling thread must be a {@link Looper} thread, which is the thread on which the * The calling thread must be a {@link Looper} thread, which is the thread on which the
* {@link Callback} will be called. * {@link Callback} will be called.
* *
* @param <T> The type of the loadable.
* @param loadable The {@link Loadable} to load. * @param loadable The {@link Loadable} to load.
* @param callback A callback to called when the load ends. * @param callback A callback to called when the load ends.
* @param defaultMinRetryCount The minimum number of times the load must be retried before * @param defaultMinRetryCount The minimum number of times the load must be retried before
......
...@@ -97,7 +97,8 @@ public final class Assertions { ...@@ -97,7 +97,8 @@ public final class Assertions {
/** /**
* Throws {@link NullPointerException} if {@code reference} is null. * Throws {@link NullPointerException} if {@code reference} is null.
* *
* @param reference An object reference. * @param <T> The type of the reference.
* @param reference The reference.
* @return The non-null reference that was validated. * @return The non-null reference that was validated.
* @throws NullPointerException If {@code reference} is null. * @throws NullPointerException If {@code reference} is null.
*/ */
...@@ -111,7 +112,8 @@ public final class Assertions { ...@@ -111,7 +112,8 @@ public final class Assertions {
/** /**
* Throws {@link NullPointerException} if {@code reference} is null. * Throws {@link NullPointerException} if {@code reference} is null.
* *
* @param reference An object reference. * @param <T> The type of the reference.
* @param reference The reference.
* @param errorMessage The exception message to use if the check fails. The message is converted * @param errorMessage The exception message to use if the check fails. The message is converted
* to a string using {@link String#valueOf(Object)}. * to a string using {@link String#valueOf(Object)}.
* @return The non-null reference that was validated. * @return The non-null reference that was validated.
......
...@@ -198,16 +198,6 @@ public final class NalUnitUtil { ...@@ -198,16 +198,6 @@ public final class NalUnitUtil {
} }
/** /**
* Constructs and returns a NAL unit with a start code followed by the data in {@code atom}.
*/
public static byte[] parseChildNalUnit(ParsableByteArray atom) {
int length = atom.readUnsignedShort();
int offset = atom.getPosition();
atom.skipBytes(length);
return CodecSpecificDataUtil.buildNalUnit(atom.data, offset, length);
}
/**
* Returns the type of the NAL unit in {@code data} that starts at {@code offset}. * Returns the type of the NAL unit in {@code data} that starts at {@code offset}.
* *
* @param data The data to search. * @param data The data to search.
......
...@@ -36,6 +36,8 @@ public final class ParsableByteArray { ...@@ -36,6 +36,8 @@ public final class ParsableByteArray {
/** /**
* Creates a new instance with {@code length} bytes. * Creates a new instance with {@code length} bytes.
*
* @param length The length of the array.
*/ */
public ParsableByteArray(int length) { public ParsableByteArray(int length) {
this.data = new byte[length]; this.data = new byte[length];
...@@ -44,6 +46,8 @@ public final class ParsableByteArray { ...@@ -44,6 +46,8 @@ public final class ParsableByteArray {
/** /**
* Creates a new instance wrapping {@code data}. * Creates a new instance wrapping {@code data}.
*
* @param data The array to wrap.
*/ */
public ParsableByteArray(byte[] data) { public ParsableByteArray(byte[] data) {
this.data = data; this.data = data;
...@@ -135,6 +139,7 @@ public final class ParsableByteArray { ...@@ -135,6 +139,7 @@ public final class ParsableByteArray {
/** /**
* Moves the reading offset by {@code bytes}. * Moves the reading offset by {@code bytes}.
* *
* @param bytes The number of bytes to skip.
* @throws IllegalArgumentException Thrown if the new position is neither in nor at the end of the * @throws IllegalArgumentException Thrown if the new position is neither in nor at the end of the
* array. * array.
*/ */
...@@ -157,7 +162,10 @@ public final class ParsableByteArray { ...@@ -157,7 +162,10 @@ public final class ParsableByteArray {
/** /**
* Reads the next {@code length} bytes into {@code buffer} at {@code offset}. * Reads the next {@code length} bytes into {@code buffer} at {@code offset}.
* *
* @see System#arraycopy * @see System#arraycopy(Object, int, Object, int, int)
* @param buffer The array into which the read data should be written.
* @param offset The offset in {@code buffer} at which the read data should be written.
* @param length The number of bytes to read.
*/ */
public void readBytes(byte[] buffer, int offset, int length) { public void readBytes(byte[] buffer, int offset, int length) {
System.arraycopy(data, position, buffer, offset, length); System.arraycopy(data, position, buffer, offset, length);
...@@ -168,6 +176,8 @@ public final class ParsableByteArray { ...@@ -168,6 +176,8 @@ public final class ParsableByteArray {
* Reads the next {@code length} bytes into {@code buffer}. * Reads the next {@code length} bytes into {@code buffer}.
* *
* @see ByteBuffer#put(byte[], int, int) * @see ByteBuffer#put(byte[], int, int)
* @param buffer The {@link ByteBuffer} into which the read data should be written.
* @param length The number of bytes to read.
*/ */
public void readBytes(ByteBuffer buffer, int length) { public void readBytes(ByteBuffer buffer, int length) {
buffer.put(data, position, length); buffer.put(data, position, length);
......
...@@ -78,9 +78,10 @@ public final class ParsableNalUnitBitArray { ...@@ -78,9 +78,10 @@ public final class ParsableNalUnitBitArray {
} }
/** /**
* Returns whether it is possible to read {@code n} bits starting from the current offset. The * Returns whether it's possible to read {@code n} bits starting from the current offset. The
* offset is not modified. * offset is not modified.
* *
* @param n The number of bits.
* @return Whether it is possible to read {@code n} bits. * @return Whether it is possible to read {@code n} bits.
*/ */
public boolean canReadBits(int n) { public boolean canReadBits(int n) {
......
...@@ -29,6 +29,8 @@ public final class TraceUtil { ...@@ -29,6 +29,8 @@ public final class TraceUtil {
* Writes a trace message to indicate that a given section of code has begun. * Writes a trace message to indicate that a given section of code has begun.
* *
* @see android.os.Trace#beginSection(String) * @see android.os.Trace#beginSection(String)
* @param sectionName The name of the code section to appear in the trace. This may be at most 127
* Unicode code units long.
*/ */
public static void beginSection(String sectionName) { public static void beginSection(String sectionName) {
if (ExoPlayerLibraryInfo.TRACE_ENABLED && Util.SDK_INT >= 18) { if (ExoPlayerLibraryInfo.TRACE_ENABLED && Util.SDK_INT >= 18) {
......
...@@ -17,6 +17,7 @@ package com.google.android.exoplayer2.video; ...@@ -17,6 +17,7 @@ package com.google.android.exoplayer2.video;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.ParserException; import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.util.CodecSpecificDataUtil;
import com.google.android.exoplayer2.util.NalUnitUtil; import com.google.android.exoplayer2.util.NalUnitUtil;
import com.google.android.exoplayer2.util.NalUnitUtil.SpsData; import com.google.android.exoplayer2.util.NalUnitUtil.SpsData;
import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.ParsableByteArray;
...@@ -52,11 +53,11 @@ public final class AvcConfig { ...@@ -52,11 +53,11 @@ public final class AvcConfig {
List<byte[]> initializationData = new ArrayList<>(); List<byte[]> initializationData = new ArrayList<>();
int numSequenceParameterSets = data.readUnsignedByte() & 0x1F; int numSequenceParameterSets = data.readUnsignedByte() & 0x1F;
for (int j = 0; j < numSequenceParameterSets; j++) { for (int j = 0; j < numSequenceParameterSets; j++) {
initializationData.add(NalUnitUtil.parseChildNalUnit(data)); initializationData.add(buildNalUnitForChild(data));
} }
int numPictureParameterSets = data.readUnsignedByte(); int numPictureParameterSets = data.readUnsignedByte();
for (int j = 0; j < numPictureParameterSets; j++) { for (int j = 0; j < numPictureParameterSets; j++) {
initializationData.add(NalUnitUtil.parseChildNalUnit(data)); initializationData.add(buildNalUnitForChild(data));
} }
int width = Format.NO_VALUE; int width = Format.NO_VALUE;
...@@ -86,4 +87,11 @@ public final class AvcConfig { ...@@ -86,4 +87,11 @@ public final class AvcConfig {
this.pixelWidthAspectRatio = pixelWidthAspectRatio; this.pixelWidthAspectRatio = pixelWidthAspectRatio;
} }
private static byte[] buildNalUnitForChild(ParsableByteArray data) {
int length = data.readUnsignedShort();
int offset = data.getPosition();
data.skipBytes(length);
return CodecSpecificDataUtil.buildNalUnit(data.data, offset, length);
}
} }
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="76 50 469 149" width="469pt" height="149pt" xmlns:dc="http://purl.org/dc/elements/1.1/"><metadata> Produced by OmniGraffle 6.6 <dc:date>2016-08-19 23:45:45 +0000</dc:date></metadata><defs><font-face font-family="Helvetica" font-size="10" units-per-em="1000" underline-position="-75.683594" underline-thickness="49.316406" slope="0" x-height="522.94922" cap-height="717.28516" ascent="770.01953" descent="-229.98047" font-weight="500"><font-face-src><font-face-name name="Helvetica"/></font-face-src></font-face><marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker" viewBox="-1 -4 10 8" markerWidth="10" markerHeight="8" color="black"><g><path d="M 8 0 L 0 -3 L 0 3 Z" fill="currentColor" stroke="currentColor" stroke-width="1"/></g></marker><marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker_2" viewBox="-9 -4 10 8" markerWidth="10" markerHeight="8" color="black"><g><path d="M -8 0 L 0 3 L 0 -3 Z" fill="currentColor" stroke="currentColor" stroke-width="1"/></g></marker></defs><g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1"><title>Canvas 1</title><rect fill="white" width="836" height="1e3"/><g><title>Layer 1</title><path d="M 105.42796 107.802954 L 186.75844 107.802954 C 196.37867 107.802954 204.1864 115.13864 204.1864 124.17725 C 204.1864 133.215865 196.37867 140.55155 186.75844 140.55155 L 105.42796 140.55155 C 95.807726 140.55155 88 133.215865 88 124.17725 C 88 115.13864 95.807726 107.802954 105.42796 107.802954" fill="white"/><path d="M 105.42796 107.802954 L 186.75844 107.802954 C 196.37867 107.802954 204.1864 115.13864 204.1864 124.17725 C 204.1864 133.215865 196.37867 140.55155 186.75844 140.55155 L 105.42796 140.55155 C 95.807726 140.55155 88 133.215865 88 124.17725 C 88 115.13864 95.807726 107.802954 105.42796 107.802954" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(104.61864 118.17725)" fill="black"><tspan font-family="Helvetica" font-size="10" font-weight="500" x="22.018994" y="10" textLength="38.911133">Disabled</tspan></text><path d="M 270.08476 107.802954 L 351.41524 107.802954 C 361.03547 107.802954 368.8432 115.13864 368.8432 124.17725 C 368.8432 133.215865 361.03547 140.55155 351.41524 140.55155 L 270.08476 140.55155 C 260.46453 140.55155 252.6568 133.215865 252.6568 124.17725 C 252.6568 115.13864 260.46453 107.802954 270.08476 107.802954" fill="white"/><path d="M 270.08476 107.802954 L 351.41524 107.802954 C 361.03547 107.802954 368.8432 115.13864 368.8432 124.17725 C 368.8432 133.215865 361.03547 140.55155 351.41524 140.55155 L 270.08476 140.55155 C 260.46453 140.55155 252.6568 133.215865 252.6568 124.17725 C 252.6568 115.13864 260.46453 107.802954 270.08476 107.802954" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(269.27544 118.17725)" fill="black"><tspan font-family="Helvetica" font-size="10" font-weight="500" x="23.12495" y="10" textLength="36.699219">Enabled</tspan></text><path d="M 434.74156 107.802954 L 516.07204 107.802954 C 525.69227 107.802954 533.5 115.13864 533.5 124.17725 C 533.5 133.215865 525.69227 140.55155 516.07204 140.55155 L 434.74156 140.55155 C 425.12133 140.55155 417.3136 133.215865 417.3136 124.17725 C 417.3136 115.13864 425.12133 107.802954 434.74156 107.802954" fill="white"/><path d="M 434.74156 107.802954 L 516.07204 107.802954 C 525.69227 107.802954 533.5 115.13864 533.5 124.17725 C 533.5 133.215865 525.69227 140.55155 516.07204 140.55155 L 434.74156 140.55155 C 425.12133 140.55155 417.3136 133.215865 417.3136 124.17725 C 417.3136 115.13864 425.12133 107.802954 434.74156 107.802954" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(433.93224 118.17725)" fill="black"><tspan font-family="Helvetica" font-size="10" font-weight="500" x="25.353955" y="10" textLength="32.24121">Started</tspan></text><path d="M 162.26839 107.80295 C 176.23115 95.948754 198.36057 82 225.18697 82 C 247.77722 82 268.5539 91.891277 283.97575 102.093746" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><path d="M 327.9848 107.80295 C 342.4642 96.22723 365.02566 82.75991 391.62577 82.75991 C 413.90596 82.75991 434.01552 92.20818 448.9453 102.0793" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><path d="M 170.59629 146.55037 C 184.3631 156.23277 203.19701 165.39131 225.18697 165.39131 C 251.72524 165.39131 275.76067 152.052325 291.55185 140.55155" marker-start="url(#FilledArrow_Marker_2)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><path d="M 336.04516 146.43053 C 350.2473 156.15705 369.5451 165.39131 391.62577 165.39131 C 418.16404 165.39131 441.62272 152.052325 456.91664 140.55155" marker-start="url(#FilledArrow_Marker_2)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><rect x="204.5238" y="59.24335" width="41" height="22" fill="white" fill-opacity="0"/><text transform="translate(209.5238 64.24335)" fill="black"><tspan font-family="Helvetica" font-size="10" font-weight="500" x=".48535156" y="10" textLength="30.029297">enable</tspan></text><rect x="375.43315" y="60.010955" width="30" height="22" fill="white" fill-opacity="0"/><text transform="translate(380.43315 65.010955)" fill="black"><tspan font-family="Helvetica" font-size="10" font-weight="500" x=".2758789" y="10" textLength="19.448242">start</tspan></text><rect x="380.333" y="167.29073" width="29" height="22" fill="white" fill-opacity="0"/><text transform="translate(385.333 172.29073)" fill="black"><tspan font-family="Helvetica" font-size="10" font-weight="500" x=".049316406" y="10" textLength="18.901367">stop</tspan></text><rect x="203.9995" y="167.34611" width="42" height="22" fill="white" fill-opacity="0"/><text transform="translate(208.9995 172.34611)" fill="black"><tspan font-family="Helvetica" font-size="10" font-weight="500" x=".15527344" y="10" textLength="31.689453">disable</tspan></text><path d="M 299.91552 140.55155 C 298.44827 143.94036 297.47889 147.48797 297.61673 150.80519 C 298.10895 162.65028 305.18498 166.24068 312.48739 165.98766 C 319.7356 165.73652 323.82378 161.81603 323.40274 150.17454" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><path d="M 464.60307 140.55155 C 463.23672 143.79583 462.35394 147.18246 462.5055 150.36634 C 463.06342 162.08711 470.07374 165.80183 477.37615 165.54882 C 484.5288 165.30099 488.66725 161.36064 488.30968 150.18478" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><rect x="269.9804" y="167.72773" width="76" height="22" fill="white" fill-opacity="0"/><text transform="translate(274.9804 172.72773)" fill="black"><tspan font-family="Helvetica" font-size="10" font-weight="500" x=".48535156" y="10" textLength="65.029297">replaceStream</tspan></text><rect x="436.50835" y="167.44093" width="76" height="22" fill="white" fill-opacity="0"/><text transform="translate(441.50835 172.44093)" fill="black"><tspan font-family="Helvetica" font-size="10" font-weight="500" x=".48535156" y="10" textLength="65.029297">replaceStream</tspan></text></g></g></svg>
...@@ -26,6 +26,7 @@ import com.google.android.exoplayer2.ExoPlayerFactory; ...@@ -26,6 +26,7 @@ import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.SimpleExoPlayer; import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.audio.AudioRendererEventListener;
import com.google.android.exoplayer2.audio.AudioTrack; import com.google.android.exoplayer2.audio.AudioTrack;
import com.google.android.exoplayer2.decoder.DecoderCounters; import com.google.android.exoplayer2.decoder.DecoderCounters;
import com.google.android.exoplayer2.drm.DrmSessionManager; import com.google.android.exoplayer2.drm.DrmSessionManager;
...@@ -39,13 +40,14 @@ import com.google.android.exoplayer2.upstream.DataSource; ...@@ -39,13 +40,14 @@ import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter; import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.TransferListener; import com.google.android.exoplayer2.upstream.TransferListener;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.VideoRendererEventListener;
import junit.framework.Assert; import junit.framework.Assert;
/** /**
* A {@link HostedTest} for {@link ExoPlayer} playback tests. * A {@link HostedTest} for {@link ExoPlayer} playback tests.
*/ */
public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListener, public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListener,
SimpleExoPlayer.DebugListener { AudioRendererEventListener, VideoRendererEventListener {
static { static {
// ExoPlayer's AudioTrack class is able to work around spurious timestamps reported by the // ExoPlayer's AudioTrack class is able to work around spurious timestamps reported by the
...@@ -132,7 +134,8 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen ...@@ -132,7 +134,8 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
player = buildExoPlayer(host, surface, trackSelector, drmSessionManager); player = buildExoPlayer(host, surface, trackSelector, drmSessionManager);
player.setMediaSource(buildSource(host, Util.getUserAgent(host, userAgent), bandwidthMeter)); player.setMediaSource(buildSource(host, Util.getUserAgent(host, userAgent), bandwidthMeter));
player.addListener(this); player.addListener(this);
player.setDebugListener(this); player.setAudioDebugListener(this);
player.setVideoDebugListener(this);
player.setPlayWhenReady(true); player.setPlayWhenReady(true);
actionHandler = new Handler(); actionHandler = new Handler();
// Schedule any pending actions. // Schedule any pending actions.
...@@ -216,7 +219,7 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen ...@@ -216,7 +219,7 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
// Do nothing. // Do nothing.
} }
// SimpleExoPlayer.DebugListener // AudioRendererEventListener
@Override @Override
public void onAudioEnabled(DecoderCounters counters) { public void onAudioEnabled(DecoderCounters counters) {
...@@ -235,7 +238,7 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen ...@@ -235,7 +238,7 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
} }
@Override @Override
public void onAudioFormatChanged(Format format) { public void onAudioInputFormatChanged(Format format) {
Log.d(tag, "audioFormatChanged [" + format.id + "]"); Log.d(tag, "audioFormatChanged [" + format.id + "]");
} }
...@@ -246,6 +249,14 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen ...@@ -246,6 +249,14 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
} }
@Override @Override
public void onAudioTrackUnderrun(int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs) {
Log.e(tag, "audioTrackUnderrun [" + bufferSize + ", " + bufferSizeMs + ", "
+ elapsedSinceLastFeedMs + "]", null);
}
// VideoRendererEventListener
@Override
public void onVideoEnabled(DecoderCounters counters) { public void onVideoEnabled(DecoderCounters counters) {
Log.d(tag, "videoEnabled"); Log.d(tag, "videoEnabled");
} }
...@@ -257,7 +268,7 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen ...@@ -257,7 +268,7 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
} }
@Override @Override
public void onVideoFormatChanged(Format format) { public void onVideoInputFormatChanged(Format format) {
Log.d(tag, "videoFormatChanged [" + format.id + "]"); Log.d(tag, "videoFormatChanged [" + format.id + "]");
} }
...@@ -273,9 +284,14 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen ...@@ -273,9 +284,14 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
} }
@Override @Override
public void onAudioTrackUnderrun(int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs) { public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees,
Log.e(tag, "audioTrackUnderrun [" + bufferSize + ", " + bufferSizeMs + ", " float pixelWidthHeightRatio) {
+ elapsedSinceLastFeedMs + "]", null); // Do nothing.
}
@Override
public void onRenderedFirstFrame(Surface surface) {
// Do nothing.
} }
// Internal logic // Internal logic
......
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