public abstract class

BaseTrackSelection

extends java.lang.Object

implements ExoTrackSelection

 java.lang.Object

↳androidx.media3.exoplayer.trackselection.BaseTrackSelection

Subclasses:

RandomTrackSelection, AdaptiveTrackSelection, FixedTrackSelection

Gradle dependencies

compile group: 'androidx.media3', name: 'media3-exoplayer', version: '1.0.0-alpha03'

  • groupId: androidx.media3
  • artifactId: media3-exoplayer
  • version: 1.0.0-alpha03

Artifact androidx.media3:media3-exoplayer:1.0.0-alpha03 it located at Google repository (https://maven.google.com/)

Overview

An abstract base class suitable for most ExoTrackSelection implementations.

Summary

Fields
protected final TrackGroupgroup

The selected TrackGroup.

protected final intlength

The number of selected tracks within the TrackGroup.

protected final int[]tracks

The indices of the selected tracks in BaseTrackSelection.group, in order of decreasing bandwidth.

Constructors
publicBaseTrackSelection(TrackGroup group, int[] tracks[])

publicBaseTrackSelection(TrackGroup group, int[] tracks[], int type)

Methods
public booleanblacklist(int index, long exclusionDurationMs)

public voiddisable()

public voidenable()

public booleanequals(java.lang.Object obj)

public intevaluateQueueSize(long playbackPositionUs, java.util.List<MediaChunk> queue)

public final FormatgetFormat(int index)

public final intgetIndexInTrackGroup(int index)

public final FormatgetSelectedFormat()

public final intgetSelectedIndexInTrackGroup()

public final TrackGroupgetTrackGroup()

public final intgetType()

public inthashCode()

public final intindexOf(Format format)

public final intindexOf(int indexInTrackGroup)

public booleanisBlacklisted(int index, long nowMs)

public final intlength()

public voidonPlaybackSpeed(float playbackSpeed)

from java.lang.Objectclone, finalize, getClass, notify, notifyAll, toString, wait, wait, wait

Fields

protected final TrackGroup group

The selected TrackGroup.

protected final int length

The number of selected tracks within the TrackGroup. Always greater than zero.

protected final int[] tracks

The indices of the selected tracks in BaseTrackSelection.group, in order of decreasing bandwidth.

Constructors

public BaseTrackSelection(TrackGroup group, int[] tracks[])

Parameters:

group: The TrackGroup. Must not be null.
tracks: The indices of the selected tracks within the TrackGroup. Must not be null or empty. May be in any order.

public BaseTrackSelection(TrackGroup group, int[] tracks[], int type)

Parameters:

group: The TrackGroup. Must not be null.
tracks: The indices of the selected tracks within the TrackGroup. Must not be null or empty. May be in any order.
type: The type that will be returned from TrackSelection.getType().

Methods

public final int getType()

public final TrackGroup getTrackGroup()

public final int length()

public final Format getFormat(int index)

public final int getIndexInTrackGroup(int index)

public final int indexOf(Format format)

public final int indexOf(int indexInTrackGroup)

public final Format getSelectedFormat()

public final int getSelectedIndexInTrackGroup()

public void enable()

public void disable()

public void onPlaybackSpeed(float playbackSpeed)

public int evaluateQueueSize(long playbackPositionUs, java.util.List<MediaChunk> queue)

public boolean blacklist(int index, long exclusionDurationMs)

public boolean isBlacklisted(int index, long nowMs)

public int hashCode()

public boolean equals(java.lang.Object obj)

Source

/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package androidx.media3.exoplayer.trackselection;

import static java.lang.Math.max;

import android.os.SystemClock;
import androidx.annotation.Nullable;
import androidx.media3.common.C;
import androidx.media3.common.Format;
import androidx.media3.common.TrackGroup;
import androidx.media3.common.TrackSelection;
import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.exoplayer.source.chunk.MediaChunk;
import java.util.Arrays;
import java.util.List;

/** An abstract base class suitable for most {@link ExoTrackSelection} implementations. */
@UnstableApi
public abstract class BaseTrackSelection implements ExoTrackSelection {

  /** The selected {@link TrackGroup}. */
  protected final TrackGroup group;
  /** The number of selected tracks within the {@link TrackGroup}. Always greater than zero. */
  protected final int length;
  /** The indices of the selected tracks in {@link #group}, in order of decreasing bandwidth. */
  protected final int[] tracks;

  /** The type of the selection. */
  private final @Type int type;
  /** The {@link Format}s of the selected tracks, in order of decreasing bandwidth. */
  private final Format[] formats;
  /** Selected track exclusion timestamps, in order of decreasing bandwidth. */
  private final long[] excludeUntilTimes;

  // Lazily initialized hashcode.
  private int hashCode;

  /**
   * @param group The {@link TrackGroup}. Must not be null.
   * @param tracks The indices of the selected tracks within the {@link TrackGroup}. Must not be
   *     null or empty. May be in any order.
   */
  public BaseTrackSelection(TrackGroup group, int... tracks) {
    this(group, tracks, TrackSelection.TYPE_UNSET);
  }

  /**
   * @param group The {@link TrackGroup}. Must not be null.
   * @param tracks The indices of the selected tracks within the {@link TrackGroup}. Must not be
   *     null or empty. May be in any order.
   * @param type The type that will be returned from {@link TrackSelection#getType()}.
   */
  public BaseTrackSelection(TrackGroup group, int[] tracks, @Type int type) {
    Assertions.checkState(tracks.length > 0);
    this.type = type;
    this.group = Assertions.checkNotNull(group);
    this.length = tracks.length;
    // Set the formats, sorted in order of decreasing bandwidth.
    formats = new Format[length];
    for (int i = 0; i < tracks.length; i++) {
      formats[i] = group.getFormat(tracks[i]);
    }
    // Sort in order of decreasing bandwidth.
    Arrays.sort(formats, (a, b) -> b.bitrate - a.bitrate);
    // Set the format indices in the same order.
    this.tracks = new int[length];
    for (int i = 0; i < length; i++) {
      this.tracks[i] = group.indexOf(formats[i]);
    }
    excludeUntilTimes = new long[length];
  }

  // TrackSelection implementation.

  @Override
  public final int getType() {
    return type;
  }

  @Override
  public final TrackGroup getTrackGroup() {
    return group;
  }

  @Override
  public final int length() {
    return tracks.length;
  }

  @Override
  public final Format getFormat(int index) {
    return formats[index];
  }

  @Override
  public final int getIndexInTrackGroup(int index) {
    return tracks[index];
  }

  @Override
  @SuppressWarnings("ReferenceEquality")
  public final int indexOf(Format format) {
    for (int i = 0; i < length; i++) {
      if (formats[i] == format) {
        return i;
      }
    }
    return C.INDEX_UNSET;
  }

  @Override
  public final int indexOf(int indexInTrackGroup) {
    for (int i = 0; i < length; i++) {
      if (tracks[i] == indexInTrackGroup) {
        return i;
      }
    }
    return C.INDEX_UNSET;
  }

  // ExoTrackSelection specific methods.

  @Override
  public final Format getSelectedFormat() {
    return formats[getSelectedIndex()];
  }

  @Override
  public final int getSelectedIndexInTrackGroup() {
    return tracks[getSelectedIndex()];
  }

  @Override
  public void enable() {
    // Do nothing.
  }

  @Override
  public void disable() {
    // Do nothing.
  }

  @Override
  public void onPlaybackSpeed(float playbackSpeed) {
    // Do nothing.
  }

  @Override
  public int evaluateQueueSize(long playbackPositionUs, List<? extends MediaChunk> queue) {
    return queue.size();
  }

  @Override
  public boolean blacklist(int index, long exclusionDurationMs) {
    long nowMs = SystemClock.elapsedRealtime();
    boolean canExclude = isBlacklisted(index, nowMs);
    for (int i = 0; i < length && !canExclude; i++) {
      canExclude = i != index && !isBlacklisted(i, nowMs);
    }
    if (!canExclude) {
      return false;
    }
    excludeUntilTimes[index] =
        max(
            excludeUntilTimes[index],
            Util.addWithOverflowDefault(nowMs, exclusionDurationMs, Long.MAX_VALUE));
    return true;
  }

  @Override
  public boolean isBlacklisted(int index, long nowMs) {
    return excludeUntilTimes[index] > nowMs;
  }

  // Object overrides.

  @Override
  public int hashCode() {
    if (hashCode == 0) {
      hashCode = 31 * System.identityHashCode(group) + Arrays.hashCode(tracks);
    }
    return hashCode;
  }

  // Track groups are compared by identity not value, as distinct groups may have the same value.
  @Override
  @SuppressWarnings({"ReferenceEquality", "EqualsGetClass"})
  public boolean equals(@Nullable Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null || getClass() != obj.getClass()) {
      return false;
    }
    BaseTrackSelection other = (BaseTrackSelection) obj;
    return group == other.group && Arrays.equals(tracks, other.tracks);
  }
}