diff --git a/demos/cast/src/main/java/com/google/android/exoplayer2/castdemo/PlayerManager.java b/demos/cast/src/main/java/com/google/android/exoplayer2/castdemo/PlayerManager.java index 32fb65c2fa..8d78ca1112 100644 --- a/demos/cast/src/main/java/com/google/android/exoplayer2/castdemo/PlayerManager.java +++ b/demos/cast/src/main/java/com/google/android/exoplayer2/castdemo/PlayerManager.java @@ -223,10 +223,12 @@ import java.util.ArrayList; if (currentPlayer != localPlayer || tracksInfo == lastSeenTrackGroupInfo) { return; } - if (!tracksInfo.isTypeSupportedOrEmpty(C.TRACK_TYPE_VIDEO)) { + if (!tracksInfo.isTypeSupportedOrEmpty( + C.TRACK_TYPE_VIDEO, /* allowExceedsCapabilities= */ true)) { listener.onUnsupportedTrack(C.TRACK_TYPE_VIDEO); } - if (!tracksInfo.isTypeSupportedOrEmpty(C.TRACK_TYPE_AUDIO)) { + if (!tracksInfo.isTypeSupportedOrEmpty( + C.TRACK_TYPE_AUDIO, /* allowExceedsCapabilities= */ true)) { listener.onUnsupportedTrack(C.TRACK_TYPE_AUDIO); } lastSeenTrackGroupInfo = tracksInfo; diff --git a/demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java b/demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java index d0aa4d58af..eaff9a185a 100644 --- a/demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java +++ b/demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java @@ -441,10 +441,12 @@ public class PlayerActivity extends AppCompatActivity if (tracksInfo == lastSeenTracksInfo) { return; } - if (!tracksInfo.isTypeSupportedOrEmpty(C.TRACK_TYPE_VIDEO)) { + if (!tracksInfo.isTypeSupportedOrEmpty( + C.TRACK_TYPE_VIDEO, /* allowExceedsCapabilities= */ true)) { showToast(R.string.error_unsupported_video); } - if (!tracksInfo.isTypeSupportedOrEmpty(C.TRACK_TYPE_AUDIO)) { + if (!tracksInfo.isTypeSupportedOrEmpty( + C.TRACK_TYPE_AUDIO, /* allowExceedsCapabilities= */ true)) { showToast(R.string.error_unsupported_audio); } lastSeenTracksInfo = tracksInfo; diff --git a/library/common/src/main/java/com/google/android/exoplayer2/TracksInfo.java b/library/common/src/main/java/com/google/android/exoplayer2/TracksInfo.java index 328f8a4080..5a46825692 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/TracksInfo.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/TracksInfo.java @@ -25,7 +25,6 @@ import android.os.Bundle; import androidx.annotation.IntDef; import androidx.annotation.Nullable; import com.google.android.exoplayer2.source.TrackGroup; -import com.google.android.exoplayer2.trackselection.TrackSelectionParameters; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; import com.google.common.primitives.Booleans; @@ -35,11 +34,12 @@ import java.lang.annotation.RetentionPolicy; import java.util.Arrays; import java.util.List; -/** Immutable information ({@link TrackGroupInfo}) about tracks. */ +/** Information about groups of tracks. */ public final class TracksInfo implements Bundleable { /** - * Information about tracks in a {@link TrackGroup}: their {@link C.TrackType}, if their format is - * supported by the player and if they are selected for playback. + * Information about a single group of tracks, including the underlying {@link TrackGroup}, the + * {@link C.TrackType type} of tracks it contains, and the level to which each track is supported + * by the player. */ public static final class TrackGroupInfo implements Bundleable { private final TrackGroup trackGroup; @@ -74,7 +74,7 @@ public final class TracksInfo implements Bundleable { } /** - * Returns the level of support for a track in a {@link TrackGroup}. + * Returns the level of support for a specified track. * * @param trackIndex The index of the track in the {@link TrackGroup}. * @return The {@link C.FormatSupport} of the track. @@ -85,24 +85,58 @@ public final class TracksInfo implements Bundleable { } /** - * Returns if a track in a {@link TrackGroup} is supported for playback. + * Returns whether a specified track is supported for playback, without exceeding the advertised + * capabilities of the device. Equivalent to {@code isTrackSupported(trackIndex, false)}. * * @param trackIndex The index of the track in the {@link TrackGroup}. * @return True if the track's format can be played, false otherwise. */ public boolean isTrackSupported(int trackIndex) { - return trackSupport[trackIndex] == C.FORMAT_HANDLED; + return isTrackSupported(trackIndex, /* allowExceedsCapabilities= */ false); } - /** Returns if at least one track in a {@link TrackGroup} is selected for playback. */ + /** + * Returns whether a specified track is supported for playback. + * + * @param trackIndex The index of the track in the {@link TrackGroup}. + * @param allowExceedsCapabilities Whether to consider the track as supported if it has a + * supported {@link Format#sampleMimeType MIME type}, but otherwise exceeds the advertised + * capabilities of the device. For example, a video track for which there's a corresponding + * decoder whose maximum advertised resolution is exceeded by the resolution of the track. + * Such tracks may be playable in some cases. + * @return True if the track's format can be played, false otherwise. + */ + public boolean isTrackSupported(int trackIndex, boolean allowExceedsCapabilities) { + return trackSupport[trackIndex] == C.FORMAT_HANDLED + || (allowExceedsCapabilities + && trackSupport[trackIndex] == C.FORMAT_EXCEEDS_CAPABILITIES); + } + + /** Returns whether at least one track in the group is selected for playback. */ public boolean isSelected() { return Booleans.contains(trackSelected, true); } - /** Returns if at least one track in a {@link TrackGroup} is supported. */ + /** + * Returns whether at least one track in the group is supported for playback, without exceeding + * the advertised capabilities of the device. Equivalent to {@code isSupported(false)}. + */ public boolean isSupported() { + return isSupported(/* allowExceedsCapabilities= */ false); + } + + /** + * Returns whether at least one track in the group is supported for playback. + * + * @param allowExceedsCapabilities Whether to consider a track as supported if it has a + * supported {@link Format#sampleMimeType MIME type}, but otherwise exceeds the advertised + * capabilities of the device. For example, a video track for which there's a corresponding + * decoder whose maximum advertised resolution is exceeded by the resolution of the track. + * Such tracks may be playable in some cases. + */ + public boolean isSupported(boolean allowExceedsCapabilities) { for (int i = 0; i < trackSupport.length; i++) { - if (isTrackSupported(i)) { + if (isTrackSupported(i, allowExceedsCapabilities)) { return true; } } @@ -110,27 +144,24 @@ public final class TracksInfo implements Bundleable { } /** - * Returns if a track in a {@link TrackGroup} is selected for playback. + * Returns whether a specified track is selected for playback. * - *
Multiple tracks of a track group may be selected. This is common in adaptive streaming, - * where multiple tracks of different quality are selected and the player switches between them - * depending on the network and the {@link TrackSelectionParameters}. + *
Note that multiple tracks in the group may be selected. This is common in adaptive + * streaming, where tracks of different qualities are selected and the player switches between + * them during playback (e.g., based on the available network bandwidth). * - *
While this class doesn't provide which selected track is currently playing, some player - * implementations have ways of getting such information. For example ExoPlayer provides this - * information in {@code ExoTrackSelection.getSelectedFormat}. + *
This class doesn't provide a way to determine which of the selected tracks is currently
+ * playing, however some player implementations have ways of getting such information. For
+ * example, ExoPlayer provides this information via {@code ExoTrackSelection.getSelectedFormat}.
*
* @param trackIndex The index of the track in the {@link TrackGroup}.
- * @return true if the track is selected, false otherwise.
+ * @return True if the track is selected, false otherwise.
*/
public boolean isTrackSelected(int trackIndex) {
return trackSelected[trackIndex];
}
- /**
- * Returns the {@link C.TrackType} of the tracks in the {@link TrackGroup}. Tracks in a group
- * are all of the same type.
- */
+ /** Returns the {@link C.TrackType} of the group. */
public @C.TrackType int getTrackType() {
return trackType;
}
@@ -212,28 +243,49 @@ public final class TracksInfo implements Bundleable {
private final ImmutableList