提交 fb55254f 编写于 作者: O olly 提交者: 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
上级 e003c5b6
......@@ -17,13 +17,14 @@ package com.google.android.exoplayer2.demo;
import android.os.SystemClock;
import android.util.Log;
import android.view.Surface;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.SimpleExoPlayer;
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.drm.StreamingDrmSessionManager;
import com.google.android.exoplayer2.metadata.MetadataRenderer;
......@@ -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.TrackSelection;
import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.video.VideoRendererEventListener;
import java.io.IOException;
import java.text.NumberFormat;
import java.util.List;
......@@ -50,7 +52,7 @@ import java.util.Locale;
* Logs player events using {@link Log}.
*/
/* package */ final class EventLogger implements ExoPlayer.EventListener,
SimpleExoPlayer.DebugListener, AdaptiveMediaSourceEventListener,
AudioRendererEventListener, VideoRendererEventListener, AdaptiveMediaSourceEventListener,
ExtractorMediaSource.EventListener, StreamingDrmSessionManager.EventListener,
MappingTrackSelector.EventListener, MetadataRenderer.Output<List<Id3Frame>> {
......@@ -184,7 +186,7 @@ import java.util.Locale;
}
}
// SimpleExoPlayer.DebugListener
// AudioRendererEventListener
@Override
public void onAudioEnabled(DecoderCounters counters) {
......@@ -203,7 +205,7 @@ import java.util.Locale;
}
@Override
public void onAudioFormatChanged(Format format) {
public void onAudioInputFormatChanged(Format format) {
Log.d(TAG, "audioFormatChanged [" + getSessionTimeString() + ", " + getFormatString(format)
+ "]");
}
......@@ -213,6 +215,14 @@ import java.util.Locale;
Log.d(TAG, "audioDisabled [" + getSessionTimeString() + "]");
}
@Override
public void onAudioTrackUnderrun(int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs) {
printInternalError("audioTrackUnderrun [" + bufferSize + ", " + bufferSizeMs + ", "
+ elapsedSinceLastFeedMs + "]", null);
}
// VideoRendererEventListener
@Override
public void onVideoEnabled(DecoderCounters counters) {
Log.d(TAG, "videoEnabled [" + getSessionTimeString() + "]");
......@@ -225,7 +235,7 @@ import java.util.Locale;
}
@Override
public void onVideoFormatChanged(Format format) {
public void onVideoInputFormatChanged(Format format) {
Log.d(TAG, "videoFormatChanged [" + getSessionTimeString() + ", " + getFormatString(format)
+ "]");
}
......@@ -241,9 +251,14 @@ import java.util.Locale;
}
@Override
public void onAudioTrackUnderrun(int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs) {
printInternalError("audioTrackUnderrun [" + bufferSize + ", " + bufferSizeMs + ", "
+ elapsedSinceLastFeedMs + "]", null);
public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees,
float pixelWidthHeightRatio) {
// Do nothing.
}
@Override
public void onRenderedFirstFrame(Surface surface) {
// Do nothing.
}
// StreamingDrmSessionManager.EventListener
......
......@@ -275,7 +275,8 @@ public class PlayerActivity extends Activity implements OnKeyListener, OnTouchLi
drmSessionManager, preferExtensionDecoders);
player.addListener(this);
player.addListener(eventLogger);
player.setDebugListener(eventLogger);
player.setAudioDebugListener(eventLogger);
player.setVideoDebugListener(eventLogger);
player.setId3Output(eventLogger);
player.setTextOutput(subtitleView);
player.setVideoListener(this);
......
......@@ -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)
* @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) {
int result = stream.readData(formatHolder, buffer);
......
......@@ -22,7 +22,7 @@ import com.google.android.exoplayer2.util.Util;
import java.util.UUID;
/**
* Defines constants that are generally useful throughout the library.
* Defines constants used by the library.
*/
public final class C {
......
......@@ -44,9 +44,9 @@ public final class DefaultLoadControl implements LoadControl {
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
* player-invoked rebuffer (i.e. a rebuffer that occurs due to buffer depletion rather than a user
* action), in milliseconds.
* The default duration of media that must be buffered for playback to resume after a rebuffer,
* in milliseconds. A rebuffer is defined to be caused by buffer depletion rather than a user
* action.
*/
public static final int DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS = 5000;
......@@ -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
* resume following a user action such as a seek, in milliseconds.
* @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
* buffer depletion rather than a user action), in milliseconds.
* playback to resume after a rebuffer, in milliseconds. A rebuffer is defined to be caused by
* buffer depletion rather than a user action.
*/
public DefaultLoadControl(DefaultAllocator allocator, int minBufferMs, int maxBufferMs,
long bufferForPlaybackMs, long bufferForPlaybackAfterRebufferMs) {
......@@ -105,7 +105,7 @@ public final class DefaultLoadControl implements LoadControl {
}
@Override
public void onTrackSelections(Renderer[] renderers, TrackGroupArray trackGroups,
public void onTracksSelected(Renderer[] renderers, TrackGroupArray trackGroups,
TrackSelectionArray trackSelections) {
targetBufferSize = 0;
for (int i = 0; i < renderers.length; i++) {
......@@ -117,7 +117,7 @@ public final class DefaultLoadControl implements LoadControl {
}
@Override
public void reset() {
public void onTracksDisabled() {
targetBufferSize = 0;
isBuffering = false;
}
......
......@@ -54,14 +54,33 @@ public final class ExoPlaybackException extends Exception {
*/
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) {
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) {
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) {
return new ExoPlaybackException(TYPE_UNEXPECTED, null, cause, C.INDEX_UNSET);
}
......@@ -74,6 +93,8 @@ public final class ExoPlaybackException extends Exception {
/**
* Retrieves the underlying error when {@link #type} is {@link #TYPE_SOURCE}.
*
* @throws IllegalStateException If {@link #type} is not {@link #TYPE_SOURCE}.
*/
public IOException getSourceException() {
Assertions.checkState(type == TYPE_SOURCE);
......@@ -82,6 +103,8 @@ public final class ExoPlaybackException extends Exception {
/**
* Retrieves the underlying error when {@link #type} is {@link #TYPE_RENDERER}.
*
* @throws IllegalStateException If {@link #type} is not {@link #TYPE_RENDERER}.
*/
public Exception getRendererException() {
Assertions.checkState(type == TYPE_RENDERER);
......@@ -90,6 +113,8 @@ public final class ExoPlaybackException extends Exception {
/**
* Retrieves the underlying error when {@link #type} is {@link #TYPE_UNEXPECTED}.
*
* @throws IllegalStateException If {@link #type} is not {@link #TYPE_UNEXPECTED}.
*/
public RuntimeException getUnexpectedException() {
Assertions.checkState(type == TYPE_UNEXPECTED);
......
......@@ -157,8 +157,8 @@ public interface ExoPlayer {
/**
* Handles a message delivered to the component. Called on the playback thread.
*
* @param messageType An integer identifying the type of message.
* @param message The message object.
* @param messageType The message type.
* @param message The message.
* @throws ExoPlaybackException If an error occurred whilst handling the message.
*/
void handleMessage(int messageType, Object message) throws ExoPlaybackException;
......@@ -170,14 +170,23 @@ public interface ExoPlayer {
*/
final class ExoPlayerMessage {
/**
* The target to receive the message.
*/
public final ExoPlayerComponent target;
/**
* The type of the message.
*/
public final int messageType;
/**
* The message.
*/
public final Object message;
/**
* @param target The target of the message.
* @param messageType An integer identifying the type of message.
* @param message The message object.
* @param messageType The message type.
* @param message The message.
*/
public ExoPlayerMessage(ExoPlayerComponent target, int messageType, Object message) {
this.target = target;
......
......@@ -21,7 +21,7 @@ import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.trackselection.TrackSelector;
/**
* A factory for instantiating {@link ExoPlayer} instances.
* A factory for {@link ExoPlayer} instances.
*/
public final class ExoPlayerFactory {
......@@ -34,9 +34,8 @@ public final class ExoPlayerFactory {
private ExoPlayerFactory() {}
/**
* Obtains a {@link SimpleExoPlayer} instance.
* <p>
* Must be called from a thread that has an associated {@link Looper}.
* Creates a {@link SimpleExoPlayer} instance. Must be called from a thread that has an associated
* {@link Looper}.
*
* @param context A {@link Context}.
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
......@@ -46,9 +45,8 @@ public final class ExoPlayerFactory {
}
/**
* Obtains a {@link SimpleExoPlayer} instance.
* <p>
* Must be called from a thread that has an associated {@link Looper}.
* Creates a {@link SimpleExoPlayer} instance. Must be called from a thread that has an associated
* {@link Looper}.
*
* @param context A {@link Context}.
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
......@@ -62,9 +60,8 @@ public final class ExoPlayerFactory {
}
/**
* Obtains a {@link SimpleExoPlayer} instance.
* <p>
* Must be called from a thread that has an associated {@link Looper}.
* Creates a {@link SimpleExoPlayer} instance. Must be called from a thread that has an associated
* {@link Looper}.
*
* @param context A {@link Context}.
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
......@@ -83,9 +80,8 @@ public final class ExoPlayerFactory {
}
/**
* Obtains a {@link SimpleExoPlayer} instance.
* <p>
* Must be called from a thread that has an associated {@link Looper}.
* Creates a {@link SimpleExoPlayer} instance. Must be called from a thread that has an associated
* {@link Looper}.
*
* @param context A {@link Context}.
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
......@@ -106,9 +102,8 @@ public final class ExoPlayerFactory {
}
/**
* Obtains an {@link ExoPlayer} instance.
* <p>
* Must be called from a thread that has an associated {@link Looper}.
* Creates an {@link ExoPlayer} instance. 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 trackSelector The {@link TrackSelector} that will be used by the instance.
......@@ -118,9 +113,8 @@ public final class ExoPlayerFactory {
}
/**
* Obtains an {@link ExoPlayer} instance.
* <p>
* Must be called from a thread that has an associated {@link Looper}.
* Creates an {@link ExoPlayer} instance. 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 trackSelector The {@link TrackSelector} that will be used by the instance.
......
......@@ -636,7 +636,7 @@ import java.io.IOException;
loadingPeriod = null;
timeline = null;
bufferAheadPeriodCount = 0;
loadControl.reset();
loadControl.onTracksDisabled();
setIsLoading(false);
}
......@@ -1253,7 +1253,7 @@ import java.io.IOException;
}
// The track selection has changed.
loadControl.onTrackSelections(renderers, mediaPeriod.getTrackGroups(), trackSelections);
loadControl.onTracksSelected(renderers, mediaPeriod.getTrackGroups(), trackSelections);
return positionUs;
}
......
......@@ -18,12 +18,12 @@ package com.google.android.exoplayer2;
/**
* Information about the ExoPlayer library.
*/
public final class ExoPlayerLibraryInfo {
public interface ExoPlayerLibraryInfo {
/**
* 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.
......@@ -32,20 +32,18 @@ public final class ExoPlayerLibraryInfo {
* corresponding integer version 1002003 (001-002-003), and "123.45.6" has the corresponding
* 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}
* 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}
* trace enabled.
*/
public static final boolean TRACE_ENABLED = true;
private ExoPlayerLibraryInfo() {}
boolean TRACE_ENABLED = true;
}
......@@ -27,7 +27,6 @@ import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
......@@ -36,24 +35,14 @@ import java.util.List;
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;
/**
* Indicates that the track should be selected if user preferences do not state otherwise.
*/
public static final int SELECTION_FLAG_DEFAULT = 1;
/**
* Indicates that the track must be displayed. Only applies to text tracks.
*/
......@@ -595,6 +584,9 @@ public final class Format implements Parcelable {
dest.writeParcelable(drmInitData, 0);
}
/**
* {@link Creator} implementation.
*/
public static final Creator<Format> CREATOR = new Creator<Format>() {
@Override
......
......@@ -16,12 +16,12 @@
package com.google.android.exoplayer2;
/**
* Holds a {@link Format} and corresponding drm scheme initialization data.
* Holds a {@link Format}.
*/
public final class FormatHolder {
/**
* The format of the media.
* The held {@link Format}.
*/
public Format format;
......
......@@ -30,16 +30,16 @@ public interface LoadControl {
* Called by the player when a track selection occurs.
*
* @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.
*/
void onTrackSelections(Renderer[] renderers, TrackGroupArray trackGroups,
void onTracksSelected(Renderer[] renderers, TrackGroupArray trackGroups,
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.
......@@ -51,7 +51,9 @@ public interface LoadControl {
* started or resumed.
*
* @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.
*/
boolean shouldStartPlayback(long bufferedDurationUs, boolean rebuffering);
......
......@@ -18,7 +18,7 @@ package com.google.android.exoplayer2;
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 {
......@@ -26,14 +26,24 @@ public class ParserException extends IOException {
super();
}
/**
* @param message The detail message for the exception.
*/
public ParserException(String message) {
super(message);
}
/**
* @param cause The cause for the exception.
*/
public ParserException(Throwable cause) {
super(cause);
}
/**
* @param message The detail message for the exception.
* @param cause The cause for the exception.
*/
public ParserException(String message, Throwable cause) {
super(message, cause);
}
......
......@@ -21,15 +21,14 @@ import com.google.android.exoplayer2.util.MediaClock;
import java.io.IOException;
/**
* Renders media samples read from a {@link SampleStream}.
* Renders media read from a {@link SampleStream}.
* <p>
* Internally, a renderer's lifecycle is managed by the owning {@link ExoPlayer}. The player will
* transition its renderers through various states as the overall playback state changes. The valid
* state transitions are shown below, annotated with the methods that are called during each
* transition.
* <p align="center"><img src="doc-files/renderer-states.png"
* alt="Renderer state transitions"
* border="0"></p>
* Internally, a renderer's lifecycle is managed by the owning {@link ExoPlayer}. The renderer is
* transitioned through various states as the overall playback state changes. The valid state
* transitions are shown below, annotated with the methods that are called during each transition.
* <p align="center">
* <img src="doc-files/renderer-states.svg" alt="Renderer state transitions">
* </p>
*/
public interface Renderer extends ExoPlayerComponent {
......@@ -38,8 +37,8 @@ public interface Renderer extends ExoPlayerComponent {
*/
int STATE_DISABLED = 0;
/**
* The renderer is enabled but not started. A renderer in this state will typically hold any
* resources that it requires for rendering (e.g. media decoders).
* The renderer is enabled but not started. A renderer in this state is not actively rendering
* media, but will typically hold resources that it requires for rendering (e.g. media decoders).
*/
int STATE_ENABLED = 1;
/**
......@@ -88,7 +87,7 @@ public interface Renderer extends ExoPlayerComponent {
int getState();
/**
* Enable the renderer to consume from the specified {@link SampleStream}.
* Enables the renderer to consume from the specified {@link SampleStream}.
* <p>
* This method may be called when the renderer is in the following states:
* {@link #STATE_DISABLED}.
......@@ -165,7 +164,7 @@ public interface Renderer extends ExoPlayerComponent {
void maybeThrowStreamError() throws IOException;
/**
* Called when a position discontinuity is encountered.
* Signals to the renderer that a position discontinuity has occurred.
* <p>
* After a position discontinuity, the renderer's {@link SampleStream} is guaranteed to provide
* samples starting from a key frame.
......@@ -231,7 +230,7 @@ public interface Renderer extends ExoPlayerComponent {
boolean isEnded();
/**
* Stops the renderer.
* Stops the renderer, transitioning it to the {@link #STATE_ENABLED} state.
* <p>
* This method may be called when the renderer is in the following states:
* {@link #STATE_STARTED}.
......@@ -241,7 +240,7 @@ public interface Renderer extends ExoPlayerComponent {
void stop() throws ExoPlaybackException;
/**
* Disable the renderer.
* Disable the renderer, transitioning it to the {@link #STATE_DISABLED} state.
* <p>
* This method may be called when the renderer is in the following states:
* {@link #STATE_ENABLED}.
......
......@@ -33,30 +33,30 @@ public interface RendererCapabilities {
*/
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.
* <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
* by the underlying H264 decoder.
*/
int FORMAT_EXCEEDS_CAPABILITIES = 0b10;
/**
* 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.
* <p>
* 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;
/**
* 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
* mimeType.
* mime type.
* <p>
* 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;
......@@ -80,19 +80,23 @@ public interface RendererCapabilities {
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()
* @return One of the {@code TRACK_TYPE_*} constants defined in {@link C}.
*/
int getTrackType();
/**
* Returns the extent to which the {@link Renderer} supports a given format.
* <p>
* The returned value is the bitwise OR of two properties:
* Returns the extent to which the {@link Renderer} supports a given format. The returned value is
* the bitwise OR of two properties:
* <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_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
* {@link #ADAPTIVE_NOT_SUPPORTED}.</li>
* </ul>
......@@ -107,10 +111,10 @@ public interface RendererCapabilities {
/**
* 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
* 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}.
* @throws ExoPlaybackException If an error occurs.
*/
......
......@@ -45,39 +45,44 @@ import java.util.ArrayList;
import java.util.List;
/**
* An {@link ExoPlayer} that uses default {@link Renderer} components.
* <p>
* Instances of this class can be obtained from {@link ExoPlayerFactory}.
* An {@link ExoPlayer} that uses default {@link Renderer} components. Instances can be obtained
* from {@link ExoPlayerFactory}.
*/
@TargetApi(16)
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 {
/**
* 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,
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);
}
/**
* 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";
......@@ -97,7 +102,8 @@ public final class SimpleExoPlayer implements ExoPlayer {
private TextRenderer.Output textOutput;
private MetadataRenderer.Output<List<Id3Frame>> id3Output;
private VideoListener videoListener;
private DebugListener debugListener;
private AudioRendererEventListener audioDebugListener;
private VideoRendererEventListener videoDebugListener;
private DecoderCounters videoDecoderCounters;
private DecoderCounters audioDecoderCounters;
private int audioSessionId;
......@@ -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.
*/
public void setDebugListener(DebugListener listener) {
debugListener = listener;
public void setAudioDebugListener(AudioRendererEventListener listener) {
audioDebugListener = listener;
}
/**
......@@ -606,16 +621,16 @@ public final class SimpleExoPlayer implements ExoPlayer {
@Override
public void onVideoEnabled(DecoderCounters counters) {
videoDecoderCounters = counters;
if (debugListener != null) {
debugListener.onVideoEnabled(counters);
if (videoDebugListener != null) {
videoDebugListener.onVideoEnabled(counters);
}
}
@Override
public void onVideoDecoderInitialized(String decoderName, long initializedTimestampMs,
long initializationDurationMs) {
if (debugListener != null) {
debugListener.onVideoDecoderInitialized(decoderName, initializedTimestampMs,
if (videoDebugListener != null) {
videoDebugListener.onVideoDecoderInitialized(decoderName, initializedTimestampMs,
initializationDurationMs);
}
}
......@@ -623,15 +638,15 @@ public final class SimpleExoPlayer implements ExoPlayer {
@Override
public void onVideoInputFormatChanged(Format format) {
videoFormat = format;
if (debugListener != null) {
debugListener.onVideoFormatChanged(format);
if (videoDebugListener != null) {
videoDebugListener.onVideoInputFormatChanged(format);
}
}
@Override
public void onDroppedFrames(int count, long elapsed) {
if (debugListener != null) {
debugListener.onDroppedFrames(count, elapsed);
if (videoDebugListener != null) {
videoDebugListener.onDroppedFrames(count, elapsed);
}
}
......@@ -642,6 +657,10 @@ public final class SimpleExoPlayer implements ExoPlayer {
videoListener.onVideoSizeChanged(width, height, unappliedRotationDegrees,
pixelWidthHeightRatio);
}
if (videoDebugListener != null) {
videoDebugListener.onVideoSizeChanged(width, height, unappliedRotationDegrees,
pixelWidthHeightRatio);
}
}
@Override
......@@ -649,12 +668,15 @@ public final class SimpleExoPlayer implements ExoPlayer {
if (videoListener != null) {
videoListener.onRenderedFirstFrame(surface);
}
if (videoDebugListener != null) {
videoDebugListener.onRenderedFirstFrame(surface);
}
}
@Override
public void onVideoDisabled(DecoderCounters counters) {
if (debugListener != null) {
debugListener.onVideoDisabled(counters);
if (videoDebugListener != null) {
videoDebugListener.onVideoDisabled(counters);
}
videoFormat = null;
videoDecoderCounters = null;
......@@ -665,24 +687,24 @@ public final class SimpleExoPlayer implements ExoPlayer {
@Override
public void onAudioEnabled(DecoderCounters counters) {
audioDecoderCounters = counters;
if (debugListener != null) {
debugListener.onAudioEnabled(counters);
if (audioDebugListener != null) {
audioDebugListener.onAudioEnabled(counters);
}
}
@Override
public void onAudioSessionId(int sessionId) {
audioSessionId = sessionId;
if (debugListener != null) {
debugListener.onAudioSessionId(sessionId);
if (audioDebugListener != null) {
audioDebugListener.onAudioSessionId(sessionId);
}
}
@Override
public void onAudioDecoderInitialized(String decoderName, long initializedTimestampMs,
long initializationDurationMs) {
if (debugListener != null) {
debugListener.onAudioDecoderInitialized(decoderName, initializedTimestampMs,
if (audioDebugListener != null) {
audioDebugListener.onAudioDecoderInitialized(decoderName, initializedTimestampMs,
initializationDurationMs);
}
}
......@@ -690,23 +712,23 @@ public final class SimpleExoPlayer implements ExoPlayer {
@Override
public void onAudioInputFormatChanged(Format format) {
audioFormat = format;
if (debugListener != null) {
debugListener.onAudioFormatChanged(format);
if (audioDebugListener != null) {
audioDebugListener.onAudioInputFormatChanged(format);
}
}
@Override
public void onAudioTrackUnderrun(int bufferSize, long bufferSizeMs,
long elapsedSinceLastFeedMs) {
if (debugListener != null) {
debugListener.onAudioTrackUnderrun(bufferSize, bufferSizeMs, elapsedSinceLastFeedMs);
if (audioDebugListener != null) {
audioDebugListener.onAudioTrackUnderrun(bufferSize, bufferSizeMs, elapsedSinceLastFeedMs);
}
}
@Override
public void onAudioDisabled(DecoderCounters counters) {
if (debugListener != null) {
debugListener.onAudioDisabled(counters);
if (audioDebugListener != null) {
audioDebugListener.onAudioDisabled(counters);
}
audioFormat = null;
audioDecoderCounters = null;
......
......@@ -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
* 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>
* The flag must be set before creating a player.
*/
......@@ -267,8 +268,10 @@ public final class AudioTrack {
}
/**
* Returns whether it is possible to play back input audio in the specified format using encoded
* audio passthrough.
* Returns whether it's possible to play audio in the specified format using encoded 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) {
return audioCapabilities != null
......@@ -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,
* SDK_INT &lt; 23.
* {@link Util#SDK_INT} &lt; 23.
*/
public void setPlaybackParams(PlaybackParams playbackParams) {
audioTrackUtil.setPlaybackParameters(playbackParams);
audioTrackUtil.setPlaybackParams(playbackParams);
}
/**
......@@ -1214,11 +1219,12 @@ public final class 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
* (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();
}
......@@ -1301,7 +1307,7 @@ public final class AudioTrack {
}
@Override
public void setPlaybackParameters(PlaybackParams playbackParams) {
public void setPlaybackParams(PlaybackParams playbackParams) {
playbackParams = (playbackParams != null ? playbackParams : new PlaybackParams())
.allowDefaults();
this.playbackParams = playbackParams;
......
......@@ -19,7 +19,7 @@ import android.annotation.TargetApi;
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 {
......
......@@ -56,9 +56,8 @@ public interface Decoder<I, O, E extends Exception> {
O dequeueOutputBuffer() throws E;
/**
* Flushes input/output buffers that have not been dequeued yet and returns ownership of any
* dequeued input buffer to the decoder. Flushes any pending output currently in the decoder. The
* caller is still responsible for releasing any dequeued output buffers.
* Flushes the decoder. Ownership of dequeued input buffers is returned to the decoder. The caller
* is still responsible for releasing any dequeued output buffers.
*/
void flush();
......
......@@ -19,7 +19,7 @@ import com.google.android.exoplayer2.C;
import java.nio.ByteBuffer;
/**
* Holds input for a decoder and corresponding metadata.
* Holds input for a decoder.
*/
public class DecoderInputBuffer extends Buffer {
......
......@@ -27,7 +27,7 @@ import java.util.List;
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 {
......
......@@ -25,7 +25,7 @@ import android.media.MediaCrypto;
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;
/**
......@@ -56,7 +56,7 @@ public interface DrmSession {
/**
* Returns a {@link MediaCrypto} for the open session.
* <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}
*
* @return A {@link MediaCrypto} for the open session.
......@@ -71,7 +71,7 @@ public interface DrmSession {
* 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).
* <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}
*
* @return Whether the open session requires a secure decoder for the specified mime type.
......@@ -82,7 +82,7 @@ public interface DrmSession {
/**
* Returns the cause of the error state.
* <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.
*/
......
......@@ -25,10 +25,8 @@ import android.os.Looper;
public interface DrmSessionManager {
/**
* Acquires a {@link DrmSession} for the specified {@link DrmInitData}.
* <p>
* The {@link DrmSession} must be returned to {@link #releaseSession(DrmSession)} when it is no
* longer required
* Acquires a {@link DrmSession} for the specified {@link DrmInitData}. 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 drmInitData DRM initialization data.
......
......@@ -31,7 +31,7 @@ public final class UnsupportedDrmException extends Exception {
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;
......
......@@ -19,7 +19,7 @@ import com.google.android.exoplayer2.C;
import java.io.IOException;
/**
* Facilitates extraction of data from a container format.
* Extracts media data from a container format.
*/
public interface Extractor {
......
......@@ -31,7 +31,7 @@ import java.io.IOException;
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() {
......
......@@ -52,7 +52,7 @@ import java.util.UUID;
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() {
......
......@@ -38,7 +38,7 @@ import java.io.IOException;
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() {
......
......@@ -50,7 +50,7 @@ import java.util.UUID;
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() {
......
......@@ -42,7 +42,7 @@ import java.util.Stack;
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() {
......
......@@ -31,7 +31,7 @@ import java.io.IOException;
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() {
......
......@@ -34,7 +34,7 @@ import java.io.IOException;
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() {
......
......@@ -33,7 +33,7 @@ import java.io.IOException;
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() {
......
......@@ -38,7 +38,7 @@ import java.io.IOException;
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() {
......
......@@ -32,7 +32,7 @@ import java.io.IOException;
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() {
......
......@@ -27,7 +27,7 @@ import com.google.android.exoplayer2.util.MimeTypes;
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)
public final class MediaCodecInfo {
......@@ -51,10 +51,24 @@ public final class MediaCodecInfo {
private final String mimeType;
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) {
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,
CodecCapabilities capabilities) {
return new MediaCodecInfo(name, mimeType, capabilities);
......
......@@ -106,6 +106,7 @@ public final class MediaCodecUtil {
* unless secure decryption really is required.
* @return A {@link MediaCodecInfo} describing the decoder, or null if no suitable decoder
* exists.
* @throws DecoderQueryException If there was an error querying the available decoders.
*/
public static MediaCodecInfo getDecoderInfo(String mimeType, boolean secure)
throws DecoderQueryException {
......@@ -122,6 +123,7 @@ public final class MediaCodecUtil {
* unless secure decryption really is required.
* @return A list of all @{link MediaCodecInfo}s for the given mime type, in the order
* given by {@link MediaCodecList}.
* @throws DecoderQueryException If there was an error querying the available decoders.
*/
public static synchronized List<MediaCodecInfo> getDecoderInfos(String mimeType,
boolean secure) throws DecoderQueryException {
......
......@@ -31,11 +31,11 @@ public interface MetadataDecoder<T> {
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 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.
*/
T decode(byte[] data, int size) throws MetadataDecoderException;
......
......@@ -36,7 +36,7 @@ import java.nio.ByteBuffer;
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.
*/
......@@ -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.
*
* @param metadata The metadata to process.
* @param metadata The metadata.
*/
void onMetadata(T metadata);
......
......@@ -314,13 +314,14 @@ public class DashManifestParser extends DefaultHandler
/**
* Parses a ContentProtection element.
*
* @param xpp The parser from which to read.
* @throws XmlPullParserException If an error occurs parsing 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
* unsupported.
**/
protected SchemeData parseContentProtection(XmlPullParser xpp)
throws XmlPullParserException, IOException {
*/
protected SchemeData parseContentProtection(XmlPullParser xpp) throws XmlPullParserException,
IOException {
byte[] data = null;
UUID uuid = null;
boolean seenPsshElement = false;
......@@ -353,7 +354,7 @@ public class DashManifestParser extends DefaultHandler
* @param xpp The XmpPullParser from which the AdaptationSet child should be parsed.
* @throws XmlPullParserException If an error occurs parsing the element.
* @throws IOException If an error occurs reading the element.
**/
*/
protected void parseAdaptationSetChild(XmlPullParser xpp)
throws XmlPullParserException, IOException {
// pass
......
......@@ -19,7 +19,7 @@ import com.google.android.exoplayer2.C;
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 {
......@@ -49,7 +49,7 @@ public interface Subtitle {
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.
* @return A list of cues that should be displayed, possibly empty.
......
......@@ -16,7 +16,7 @@
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 {
......
......@@ -16,7 +16,6 @@
package com.google.android.exoplayer2.text;
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.subrip.SubripDecoder;
import com.google.android.exoplayer2.text.ttml.TtmlDecoder;
......@@ -26,7 +25,7 @@ import com.google.android.exoplayer2.text.webvtt.WebvttDecoder;
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 {
......
......@@ -39,7 +39,7 @@ import java.util.List;
public final class TextRenderer extends BaseRenderer implements Callback {
/**
* An output for the renderer.
* Receives output from a {@link TextRenderer}.
*/
public interface Output {
......
......@@ -37,9 +37,8 @@ import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
/**
* A {@link SimpleSubtitleDecoder} for TTML supporting the DFXP presentation profile.
* <p>
* Supported features in this parser are:
* A {@link SimpleSubtitleDecoder} for TTML supporting the DFXP presentation profile. Features
* supported by this decoder are:
* <ul>
* <li>content
* <li>core
......
......@@ -18,11 +18,11 @@ package com.google.android.exoplayer2.trackselection;
import android.os.SystemClock;
import com.google.android.exoplayer2.C;
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.chunk.MediaChunk;
import com.google.android.exoplayer2.util.Assertions;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
/**
......@@ -179,4 +179,16 @@ public abstract class BaseTrackSelection implements TrackSelection {
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
}
started = true;
player.addListener(this);
run();
updateAndPost();
}
/**
......@@ -71,20 +71,52 @@ public final class DebugTextViewHelper implements Runnable, ExoPlayer.EventListe
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
public void run() {
updateTextView();
textView.postDelayed(this, REFRESH_INTERVAL_MS);
updateAndPost();
}
private void updateTextView() {
// Private methods.
private void updateAndPost() {
textView.setText(getPlayerStateString() + getPlayerWindowIndexString() + getVideoString()
+ getAudioString());
textView.removeCallbacks(this);
textView.postDelayed(this, REFRESH_INTERVAL_MS);
}
private String getPlayerStateString() {
String text = "playWhenReady:" + player.getPlayWhenReady() + " playbackState:";
switch(player.getPlaybackState()) {
switch (player.getPlaybackState()) {
case ExoPlayer.STATE_BUFFERING:
text += "buffering";
break;
......@@ -139,31 +171,4 @@ public final class DebugTextViewHelper implements Runnable, ExoPlayer.EventListe
+ " 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;
/**
* An {@link OnClickListener} that can be passed 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
* windows in the timeline of the media being played.
* make the controller's previous and next buttons seek to the previous and next windows in the
* {@link Timeline}.
*/
public class MediaControllerPrevNextClickListener implements OnClickListener {
......
......@@ -22,16 +22,18 @@ import com.google.android.exoplayer2.audio.MediaCodecAudioRenderer;
/**
* 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
* implement their own player controls and therefore not require this class.
*/
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
......@@ -65,39 +67,39 @@ public class PlayerControl implements MediaPlayerControl {
@Override
public int getBufferPercentage() {
return exoPlayer.getBufferedPercentage();
return player.getBufferedPercentage();
}
@Override
public int getCurrentPosition() {
long position = exoPlayer.getCurrentPosition();
long position = player.getCurrentPosition();
return position == C.TIME_UNSET ? 0 : (int) position;
}
@Override
public int getDuration() {
long duration = exoPlayer.getDuration();
long duration = player.getDuration();
return duration == C.TIME_UNSET ? 0 : (int) duration;
}
@Override
public boolean isPlaying() {
return exoPlayer.getPlayWhenReady();
return player.getPlayWhenReady();
}
@Override
public void start() {
exoPlayer.setPlayWhenReady(true);
player.setPlayWhenReady(true);
}
@Override
public void pause() {
exoPlayer.setPlayWhenReady(false);
player.setPlayWhenReady(false);
}
@Override
public void seekTo(int timeMillis) {
exoPlayer.seekTo(timeMillis);
player.seekTo(timeMillis);
}
}
......@@ -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
* {@link Callback} will be called.
*
* @param <T> The type of the loadable.
* @param loadable The {@link Loadable} to load.
* @param callback A callback to called when the load ends.
* @param defaultMinRetryCount The minimum number of times the load must be retried before
......
......@@ -97,7 +97,8 @@ public final class Assertions {
/**
* 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.
* @throws NullPointerException If {@code reference} is null.
*/
......@@ -111,7 +112,8 @@ public final class Assertions {
/**
* 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
* to a string using {@link String#valueOf(Object)}.
* @return The non-null reference that was validated.
......
......@@ -197,16 +197,6 @@ public final class NalUnitUtil {
data.clear();
}
/**
* 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}.
*
......
......@@ -36,6 +36,8 @@ public final class ParsableByteArray {
/**
* Creates a new instance with {@code length} bytes.
*
* @param length The length of the array.
*/
public ParsableByteArray(int length) {
this.data = new byte[length];
......@@ -44,6 +46,8 @@ public final class ParsableByteArray {
/**
* Creates a new instance wrapping {@code data}.
*
* @param data The array to wrap.
*/
public ParsableByteArray(byte[] data) {
this.data = data;
......@@ -135,6 +139,7 @@ public final class ParsableByteArray {
/**
* 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
* array.
*/
......@@ -157,7 +162,10 @@ public final class ParsableByteArray {
/**
* 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) {
System.arraycopy(data, position, buffer, offset, length);
......@@ -168,6 +176,8 @@ public final class ParsableByteArray {
* Reads the next {@code length} bytes into {@code buffer}.
*
* @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) {
buffer.put(data, position, length);
......
......@@ -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.
*
* @param n The number of bits.
* @return Whether it is possible to read {@code n} bits.
*/
public boolean canReadBits(int n) {
......
......@@ -29,6 +29,8 @@ public final class TraceUtil {
* Writes a trace message to indicate that a given section of code has begun.
*
* @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) {
if (ExoPlayerLibraryInfo.TRACE_ENABLED && Util.SDK_INT >= 18) {
......
......@@ -141,6 +141,7 @@ public final class Util {
* Checks whether it's necessary to request the {@link permission#READ_EXTERNAL_STORAGE}
* permission read the specified {@link Uri}s, requesting the permission if necessary.
*
* @param activity The host activity for checking and requesting the permission.
* @param uris {@link Uri}s that may require {@link permission#READ_EXTERNAL_STORAGE} to read.
* @return Whether a permission request was made.
*/
......@@ -310,104 +311,108 @@ public final class Util {
/**
* Returns the index of the largest value in an array that is less than (or optionally equal to)
* a specified key.
* a specified value.
* <p>
* The search is performed using a binary search algorithm, and so the array must be sorted.
* The search is performed using a binary search algorithm, so the array must be sorted.
*
* @param a The array to search.
* @param key The key being searched for.
* @param inclusive If the key is present in the array, whether to return the corresponding index.
* If false then the returned index corresponds to the largest value in the array that is
* strictly less than the key.
* @param stayInBounds If true, then 0 will be returned in the case that the key is smaller than
* @param value The value being searched for.
* @param inclusive If the value is present in the array, whether to return the corresponding
* index. If false then the returned index corresponds to the largest value in the array that
* is strictly less than the value.
* @param stayInBounds If true, then 0 will be returned in the case that the value is smaller than
* the smallest value in the array. If false then -1 will be returned.
*/
public static int binarySearchFloor(int[] a, int key, boolean inclusive, boolean stayInBounds) {
int index = Arrays.binarySearch(a, key);
public static int binarySearchFloor(int[] a, int value, boolean inclusive, boolean stayInBounds) {
int index = Arrays.binarySearch(a, value);
index = index < 0 ? -(index + 2) : (inclusive ? index : (index - 1));
return stayInBounds ? Math.max(0, index) : index;
}
/**
* Returns the index of the largest value in an array that is less than (or optionally equal to)
* a specified key.
* a specified value.
* <p>
* The search is performed using a binary search algorithm, and so the array must be sorted.
* The search is performed using a binary search algorithm, so the array must be sorted.
*
* @param a The array to search.
* @param key The key being searched for.
* @param inclusive If the key is present in the array, whether to return the corresponding index.
* If false then the returned index corresponds to the largest value in the array that is
* strictly less than the key.
* @param stayInBounds If true, then 0 will be returned in the case that the key is smaller than
* @param value The value being searched for.
* @param inclusive If the value is present in the array, whether to return the corresponding
* index. If false then the returned index corresponds to the largest value in the array that
* is strictly less than the value.
* @param stayInBounds If true, then 0 will be returned in the case that the value is smaller than
* the smallest value in the array. If false then -1 will be returned.
*/
public static int binarySearchFloor(long[] a, long key, boolean inclusive, boolean stayInBounds) {
int index = Arrays.binarySearch(a, key);
public static int binarySearchFloor(long[] a, long value, boolean inclusive,
boolean stayInBounds) {
int index = Arrays.binarySearch(a, value);
index = index < 0 ? -(index + 2) : (inclusive ? index : (index - 1));
return stayInBounds ? Math.max(0, index) : index;
}
/**
* Returns the index of the smallest value in an array that is greater than (or optionally equal
* to) a specified key.
* to) a specified value.
* <p>
* The search is performed using a binary search algorithm, and so the array must be sorted.
* The search is performed using a binary search algorithm, so the array must be sorted.
*
* @param a The array to search.
* @param key The key being searched for.
* @param inclusive If the key is present in the array, whether to return the corresponding index.
* If false then the returned index corresponds to the smallest value in the array that is
* strictly greater than the key.
* @param value The value being searched for.
* @param inclusive If the value is present in the array, whether to return the corresponding
* index. If false then the returned index corresponds to the largest value in the array that
* is strictly less than the value.
* @param stayInBounds If true, then {@code (a.length - 1)} will be returned in the case that the
* key is greater than the largest value in the array. If false then {@code a.length} will be
* returned.
* value is greater than the largest value in the array. If false then {@code a.length} will
* be returned.
*/
public static int binarySearchCeil(long[] a, long key, boolean inclusive, boolean stayInBounds) {
int index = Arrays.binarySearch(a, key);
public static int binarySearchCeil(long[] a, long value, boolean inclusive,
boolean stayInBounds) {
int index = Arrays.binarySearch(a, value);
index = index < 0 ? ~index : (inclusive ? index : (index + 1));
return stayInBounds ? Math.min(a.length - 1, index) : index;
}
/**
* Returns the index of the largest value in an list that is less than (or optionally equal to)
* a specified key.
* a specified value.
* <p>
* The search is performed using a binary search algorithm, and so the list must be sorted.
* The search is performed using a binary search algorithm, so the list must be sorted.
*
* @param <T> The type of values being searched.
* @param list The list to search.
* @param key The key being searched for.
* @param inclusive If the key is present in the list, whether to return the corresponding index.
* If false then the returned index corresponds to the largest value in the list that is
* strictly less than the key.
* @param stayInBounds If true, then 0 will be returned in the case that the key is smaller than
* @param value The value being searched for.
* @param inclusive If the value is present in the list, whether to return the corresponding
* index. If false then the returned index corresponds to the largest value in the list that
* is strictly less than the value.
* @param stayInBounds If true, then 0 will be returned in the case that the value is smaller than
* the smallest value in the list. If false then -1 will be returned.
*/
public static<T> int binarySearchFloor(List<? extends Comparable<? super T>> list, T key,
public static <T> int binarySearchFloor(List<? extends Comparable<? super T>> list, T value,
boolean inclusive, boolean stayInBounds) {
int index = Collections.binarySearch(list, key);
int index = Collections.binarySearch(list, value);
index = index < 0 ? -(index + 2) : (inclusive ? index : (index - 1));
return stayInBounds ? Math.max(0, index) : index;
}
/**
* Returns the index of the smallest value in an list that is greater than (or optionally equal
* to) a specified key.
* to) a specified value.
* <p>
* The search is performed using a binary search algorithm, and so the list must be sorted.
* The search is performed using a binary search algorithm, so the list must be sorted.
*
* @param <T> The type of values being searched.
* @param list The list to search.
* @param key The key being searched for.
* @param inclusive If the key is present in the list, whether to return the corresponding index.
* If false then the returned index corresponds to the smallest value in the list that is
* strictly greater than the key.
* @param value The value being searched for.
* @param inclusive If the value is present in the list, whether to return the corresponding
* index. If false then the returned index corresponds to the smallest value in the list that
* is strictly greater than the value.
* @param stayInBounds If true, then {@code (list.size() - 1)} will be returned in the case that
* the key is greater than the largest value in the list. If false then {@code list.size()}
* the value is greater than the largest value in the list. If false then {@code list.size()}
* will be returned.
*/
public static<T> int binarySearchCeil(List<? extends Comparable<? super T>> list, T key,
public static <T> int binarySearchCeil(List<? extends Comparable<? super T>> list, T value,
boolean inclusive, boolean stayInBounds) {
int index = Collections.binarySearch(list, key);
int index = Collections.binarySearch(list, value);
index = index < 0 ? ~index : (inclusive ? index : (index + 1));
return stayInBounds ? Math.min(list.size() - 1, index) : index;
}
......@@ -612,7 +617,9 @@ public final class Util {
/**
* Returns the integer equal to the big-endian concatenation of the characters in {@code string}
* as bytes. {@code string} must contain four or fewer characters.
* as bytes. The string must be no more than four characters long.
*
* @param string A string no more than four characters long.
*/
public static int getIntegerCodeForString(String string) {
int length = string.length();
......@@ -641,7 +648,11 @@ public final class Util {
return data;
}
/** Returns a hex string representation of the given byte array. */
/**
* Returns a hex string representation of the given byte array.
*
* @param bytes The byte array.
*/
public static String getHexString(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
int i = 0;
......@@ -658,7 +669,7 @@ public final class Util {
* @param objects The objects whose simple class names should be comma delimited and returned.
* @return A string with comma delimited simple names of each object's class.
*/
public static <T> String getCommaDelimitedSimpleClassNames(T[] objects) {
public static String getCommaDelimitedSimpleClassNames(Object[] objects) {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < objects.length; i++) {
stringBuilder.append(objects[i].getClass().getSimpleName());
......@@ -856,7 +867,11 @@ public final class Util {
return builder.toString();
}
/** Returns the SHA-1 digest of input as a hex string. */
/**
* Returns the SHA-1 digest of {@code input} as a hex string.
*
* @param input The string whose SHA-1 digest is required.
*/
public static String sha1(String input) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-1");
......
......@@ -17,6 +17,7 @@ package com.google.android.exoplayer2.video;
import com.google.android.exoplayer2.Format;
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.SpsData;
import com.google.android.exoplayer2.util.ParsableByteArray;
......@@ -52,11 +53,11 @@ public final class AvcConfig {
List<byte[]> initializationData = new ArrayList<>();
int numSequenceParameterSets = data.readUnsignedByte() & 0x1F;
for (int j = 0; j < numSequenceParameterSets; j++) {
initializationData.add(NalUnitUtil.parseChildNalUnit(data));
initializationData.add(buildNalUnitForChild(data));
}
int numPictureParameterSets = data.readUnsignedByte();
for (int j = 0; j < numPictureParameterSets; j++) {
initializationData.add(NalUnitUtil.parseChildNalUnit(data));
initializationData.add(buildNalUnitForChild(data));
}
int width = Format.NO_VALUE;
......@@ -86,4 +87,11 @@ public final class AvcConfig {
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;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.SimpleExoPlayer;
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.decoder.DecoderCounters;
import com.google.android.exoplayer2.drm.DrmSessionManager;
......@@ -39,13 +40,14 @@ import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.TransferListener;
import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.VideoRendererEventListener;
import junit.framework.Assert;
/**
* A {@link HostedTest} for {@link ExoPlayer} playback tests.
*/
public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListener,
SimpleExoPlayer.DebugListener {
AudioRendererEventListener, VideoRendererEventListener {
static {
// 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
player = buildExoPlayer(host, surface, trackSelector, drmSessionManager);
player.setMediaSource(buildSource(host, Util.getUserAgent(host, userAgent), bandwidthMeter));
player.addListener(this);
player.setDebugListener(this);
player.setAudioDebugListener(this);
player.setVideoDebugListener(this);
player.setPlayWhenReady(true);
actionHandler = new Handler();
// Schedule any pending actions.
......@@ -216,7 +219,7 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
// Do nothing.
}
// SimpleExoPlayer.DebugListener
// AudioRendererEventListener
@Override
public void onAudioEnabled(DecoderCounters counters) {
......@@ -235,7 +238,7 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
}
@Override
public void onAudioFormatChanged(Format format) {
public void onAudioInputFormatChanged(Format format) {
Log.d(tag, "audioFormatChanged [" + format.id + "]");
}
......@@ -245,6 +248,14 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
audioDecoderCounters.merge(counters);
}
@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) {
Log.d(tag, "videoEnabled");
......@@ -257,7 +268,7 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
}
@Override
public void onVideoFormatChanged(Format format) {
public void onVideoInputFormatChanged(Format format) {
Log.d(tag, "videoFormatChanged [" + format.id + "]");
}
......@@ -273,9 +284,14 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
}
@Override
public void onAudioTrackUnderrun(int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs) {
Log.e(tag, "audioTrackUnderrun [" + bufferSize + ", " + bufferSizeMs + ", "
+ elapsedSinceLastFeedMs + "]", null);
public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees,
float pixelWidthHeightRatio) {
// Do nothing.
}
@Override
public void onRenderedFirstFrame(Surface surface) {
// Do nothing.
}
// Internal logic
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册