diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/MappingTrackSelector.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/MappingTrackSelector.java
index 3499efdb16..30cc02936a 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/MappingTrackSelector.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/MappingTrackSelector.java
@@ -20,6 +20,7 @@ import android.util.SparseArray;
import android.util.SparseBooleanArray;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException;
+import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.RendererConfiguration;
import com.google.android.exoplayer2.source.TrackGroup;
@@ -31,7 +32,8 @@ import java.util.Map;
/**
* Base class for {@link TrackSelector}s that first establish a mapping between {@link TrackGroup}s
- * and renderers, and then from that mapping create a {@link TrackSelection} for each renderer.
+ * and {@link Renderer}s, and then from that mapping create a {@link TrackSelection} for each
+ * renderer.
*/
public abstract class MappingTrackSelector extends TrackSelector {
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelector.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelector.java
index 6c9fbfcb00..a26fee6f78 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelector.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelector.java
@@ -16,19 +16,74 @@
package com.google.android.exoplayer2.trackselection;
import com.google.android.exoplayer2.ExoPlaybackException;
+import com.google.android.exoplayer2.ExoPlayer;
+import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.RendererCapabilities;
+import com.google.android.exoplayer2.RendererConfiguration;
import com.google.android.exoplayer2.source.TrackGroupArray;
-/** Selects tracks to be consumed by available renderers. */
+/**
+ * The component of an {@link ExoPlayer} responsible for selecting tracks to be consumed by each of
+ * the player's {@link Renderer}s. The {@link DefaultTrackSelector} implementation should be
+ * suitable for most use cases.
+ *
+ *
Interactions with the player
+ * The following interactions occur between the player and its track selector during playback.
+ *
+ *
+ * - When the player is created it will initialize the track selector by calling
+ * {@link #init(InvalidationListener)}.
+ * - When the player needs to make a track selection it will call
+ * {@link #selectTracks(RendererCapabilities[], TrackGroupArray)}. This typically occurs at the
+ * start of playback, when the player starts to buffer a new period of the media being played,
+ * and when the track selector invalidates its previous selections.
+ * - The player may perform a track selection well in advance of the selected tracks becoming
+ * active, where active is defined to mean that the renderers are actually consuming media
+ * corresponding to the selection that was made. For example when playing media containing
+ * multiple periods, the track selection for a period is made when the player starts to buffer
+ * that period. Hence if the player's buffering policy is to maintain a 30 second buffer, the
+ * selection will occur approximately 30 seconds in advance of it becoming active. In fact the
+ * selection may never become active, for example if the user seeks to some other period of the
+ * media during the 30 second gap. The player indicates to the track selector when a selection
+ * it has previously made becomes active by calling {@link #onSelectionActivated(Object)}.
+ * - If the track selector wishes to indicate to the player that selections it has previously
+ * made are invalid, it can do so by calling
+ * {@link InvalidationListener#onTrackSelectionsInvalidated()} on the
+ * {@link InvalidationListener} that was passed to {@link #init(InvalidationListener)}. A
+ * track selector may wish to do this if its configuration has changed, for example if it now
+ * wishes to prefer audio tracks in a particular language. This will trigger the player to make
+ * new track selections. Note that the player will have to re-buffer in the case that the new
+ * track selection for the currently playing period differs from the one that was invalidated.
+ *
+ *
+ *
+ * Renderer configuration
+ * The {@link TrackSelectorResult} returned by
+ * {@link #selectTracks(RendererCapabilities[], TrackGroupArray)} contains not only
+ * {@link TrackSelection}s for each renderer, but also {@link RendererConfiguration}s defining
+ * configuration parameters that the renderers should apply when consuming the corresponding media.
+ * Whilst it may seem counter-intuitive for a track selector to also specify renderer configuration
+ * information, in practice the two are tightly bound together. It may only be possible to play a
+ * certain combination tracks if the renderers are configured in a particular way. Equally, it may
+ * only be possible to configure renderers in a particular way if certain tracks are selected. Hence
+ * it makes sense to determined the track selection and corresponding renderer configurations in a
+ * single step.
+ *
+ * Threading model
+ * All calls made by the player into the track selector are on the player's internal playback
+ * thread. The track selector may call {@link InvalidationListener#onTrackSelectionsInvalidated()}
+ * from any thread.
+ */
public abstract class TrackSelector {
/**
- * Notified when previous selections by a {@link TrackSelector} are no longer valid.
+ * Notified when selections previously made by a {@link TrackSelector} are no longer valid.
*/
public interface InvalidationListener {
/**
- * Called by a {@link TrackSelector} when previous selections are no longer valid.
+ * Called by a {@link TrackSelector} to indicate that selections it has previously made are no
+ * longer valid. May be called from any thread.
*/
void onTrackSelectionsInvalidated();
@@ -37,16 +92,17 @@ public abstract class TrackSelector {
private InvalidationListener listener;
/**
- * Initializes the selector.
+ * Called by the player to initialize the selector.
*
- * @param listener A listener for the selector.
+ * @param listener An invalidation listener that the selector can call to indicate that selections
+ * it has previously made are no longer valid.
*/
public final void init(InvalidationListener listener) {
this.listener = listener;
}
/**
- * Performs a track selection for renderers.
+ * Called by the player to perform a track selection.
*
* @param rendererCapabilities The {@link RendererCapabilities} of the renderers for which tracks
* are to be selected.
@@ -58,15 +114,16 @@ public abstract class TrackSelector {
TrackGroupArray trackGroups) throws ExoPlaybackException;
/**
- * Called when a {@link TrackSelectorResult} previously generated by
+ * Called by the player when a {@link TrackSelectorResult} previously generated by
* {@link #selectTracks(RendererCapabilities[], TrackGroupArray)} is activated.
*
- * @param info The value of {@link TrackSelectorResult#info} in the activated result.
+ * @param info The value of {@link TrackSelectorResult#info} in the activated selection.
*/
public abstract void onSelectionActivated(Object info);
/**
- * Invalidates all previously generated track selections.
+ * Calls {@link InvalidationListener#onTrackSelectionsInvalidated()} to invalidate all previously
+ * generated track selections.
*/
protected final void invalidate() {
if (listener != null) {
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectorResult.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectorResult.java
index 5cdb157570..cab9a689be 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectorResult.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectorResult.java
@@ -25,11 +25,11 @@ import com.google.android.exoplayer2.util.Util;
public final class TrackSelectorResult {
/**
- * The groups provided to the {@link TrackSelector}.
+ * The track groups that were provided to the {@link TrackSelector}.
*/
public final TrackGroupArray groups;
/**
- * A {@link TrackSelectionArray} containing the selection for each renderer.
+ * A {@link TrackSelectionArray} containing the track selection for each renderer.
*/
public final TrackSelectionArray selections;
/**
@@ -43,10 +43,10 @@ public final class TrackSelectorResult {
public final RendererConfiguration[] rendererConfigurations;
/**
- * @param groups The groups provided to the {@link TrackSelector}.
+ * @param groups The track groups provided to the {@link TrackSelector}.
* @param selections A {@link TrackSelectionArray} containing the selection for each renderer.
* @param info An opaque object that will be returned to
- * {@link TrackSelector#onSelectionActivated(Object)} should the selections be activated.
+ * {@link TrackSelector#onSelectionActivated(Object)} should the selection be activated.
* @param rendererConfigurations A {@link RendererConfiguration} for each renderer, to be used
* with the selections.
*/
@@ -62,7 +62,7 @@ public final class TrackSelectorResult {
* Returns whether this result is equivalent to {@code other} for all renderers.
*
* @param other The other {@link TrackSelectorResult}. May be null, in which case {@code false}
- * will be returned in all cases.
+ * will be returned.
* @return Whether this result is equivalent to {@code other} for all renderers.
*/
public boolean isEquivalent(TrackSelectorResult other) {
@@ -83,9 +83,10 @@ public final class TrackSelectorResult {
* renderer.
*
* @param other The other {@link TrackSelectorResult}. May be null, in which case {@code false}
- * will be returned in all cases.
+ * will be returned.
* @param index The renderer index to check for equivalence.
- * @return Whether this result is equivalent to {@code other} for all renderers.
+ * @return Whether this result is equivalent to {@code other} for the renderer at the specified
+ * index.
*/
public boolean isEquivalent(TrackSelectorResult other, int index) {
if (other == null) {