Move track type from TrackGroupInfo to TrackGroup
The track type is derived solely from the content. It does not depend on any runtime properties such as the player's capabilities of user track selection. Hence it belongs in TrackGroup rather than TrackGroupInfo. Note that this avoids TrackSelectionOverride from having to re-derive the track type internally. PiperOrigin-RevId: 429303312
This commit is contained in:
parent
6b606b9987
commit
265dd079e9
@ -1038,11 +1038,7 @@ public final class CastPlayer extends BasePlayer {
|
||||
final boolean[] trackSelected = new boolean[] {selected};
|
||||
trackGroupInfos[i] =
|
||||
new TracksInfo.TrackGroupInfo(
|
||||
trackType,
|
||||
trackGroups[i],
|
||||
/* adaptiveSupported= */ false,
|
||||
trackSupport,
|
||||
trackSelected);
|
||||
trackGroups[i], /* adaptiveSupported= */ false, trackSupport, trackSelected);
|
||||
}
|
||||
TrackGroupArray newTrackGroups = new TrackGroupArray(trackGroups);
|
||||
TrackSelectionArray newTrackSelections = new TrackSelectionArray(trackSelections);
|
||||
|
@ -43,6 +43,8 @@ public final class TrackGroup implements Bundleable {
|
||||
public final int length;
|
||||
/** An identifier for the track group. */
|
||||
public final String id;
|
||||
/** The type of tracks in the group. */
|
||||
public final @C.TrackType int type;
|
||||
|
||||
private final Format[] formats;
|
||||
|
||||
@ -71,6 +73,11 @@ public final class TrackGroup implements Bundleable {
|
||||
this.id = id;
|
||||
this.formats = formats;
|
||||
this.length = formats.length;
|
||||
@C.TrackType int type = MimeTypes.getTrackType(formats[0].sampleMimeType);
|
||||
if (type == C.TRACK_TYPE_UNKNOWN) {
|
||||
type = MimeTypes.getTrackType(formats[0].containerMimeType);
|
||||
}
|
||||
this.type = type;
|
||||
verifyCorrectness();
|
||||
}
|
||||
|
||||
@ -134,7 +141,7 @@ public final class TrackGroup implements Bundleable {
|
||||
return false;
|
||||
}
|
||||
TrackGroup other = (TrackGroup) obj;
|
||||
return length == other.length && id.equals(other.id) && Arrays.equals(formats, other.formats);
|
||||
return id.equals(other.id) && Arrays.equals(formats, other.formats);
|
||||
}
|
||||
|
||||
// Bundleable implementation.
|
||||
|
@ -88,7 +88,7 @@ public final class TrackSelectionOverride implements Bundleable {
|
||||
|
||||
/** Returns the {@link C.TrackType} of the overridden track group. */
|
||||
public @C.TrackType int getTrackType() {
|
||||
return MimeTypes.getTrackType(trackGroup.getFormat(0).sampleMimeType);
|
||||
return trackGroup.type;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -49,7 +49,6 @@ public final class TracksInfo implements Bundleable {
|
||||
/** The number of tracks in the group. */
|
||||
public final int length;
|
||||
|
||||
private final @C.TrackType int trackType;
|
||||
private final TrackGroup trackGroup;
|
||||
private final boolean adaptiveSupported;
|
||||
private final @C.FormatSupport int[] trackSupport;
|
||||
@ -58,23 +57,20 @@ public final class TracksInfo implements Bundleable {
|
||||
/**
|
||||
* Constructs a TrackGroupInfo.
|
||||
*
|
||||
* @param trackType The {@link C.TrackType} of the tracks in the {@code trackGroup}.
|
||||
* @param trackGroup The {@link TrackGroup} described.
|
||||
* @param adaptiveSupported Whether adaptive selections containing more than one track are
|
||||
* supported.
|
||||
* @param adaptiveSupported Whether adaptive selections containing more than one track in the
|
||||
* {@code trackGroup} are supported.
|
||||
* @param trackSupport The {@link C.FormatSupport} of each track in the {@code trackGroup}.
|
||||
* @param tracksSelected Whether a track is selected for each track in {@code trackGroup}.
|
||||
* @param tracksSelected Whether each track in the {@code trackGroup} is selected.
|
||||
*/
|
||||
@UnstableApi
|
||||
public TrackGroupInfo(
|
||||
@C.TrackType int trackType,
|
||||
TrackGroup trackGroup,
|
||||
boolean adaptiveSupported,
|
||||
@C.FormatSupport int[] trackSupport,
|
||||
boolean[] tracksSelected) {
|
||||
length = trackGroup.length;
|
||||
checkArgument(length == trackSupport.length && length == tracksSelected.length);
|
||||
this.trackType = trackType;
|
||||
this.trackGroup = trackGroup;
|
||||
this.adaptiveSupported = adaptiveSupported && length > 1;
|
||||
this.trackSupport = trackSupport.clone();
|
||||
@ -191,7 +187,7 @@ public final class TracksInfo implements Bundleable {
|
||||
|
||||
/** Returns the {@link C.TrackType} of the group. */
|
||||
public @C.TrackType int getTrackType() {
|
||||
return trackType;
|
||||
return trackGroup.type;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -203,7 +199,7 @@ public final class TracksInfo implements Bundleable {
|
||||
return false;
|
||||
}
|
||||
TrackGroupInfo that = (TrackGroupInfo) other;
|
||||
return trackType == that.trackType
|
||||
return adaptiveSupported == that.adaptiveSupported
|
||||
&& trackGroup.equals(that.trackGroup)
|
||||
&& Arrays.equals(trackSupport, that.trackSupport)
|
||||
&& Arrays.equals(trackSelected, that.trackSelected);
|
||||
@ -212,8 +208,8 @@ public final class TracksInfo implements Bundleable {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = trackGroup.hashCode();
|
||||
result = 31 * result + (adaptiveSupported ? 1 : 0);
|
||||
result = 31 * result + Arrays.hashCode(trackSupport);
|
||||
result = 31 * result + trackType;
|
||||
result = 31 * result + Arrays.hashCode(trackSelected);
|
||||
return result;
|
||||
}
|
||||
@ -225,7 +221,6 @@ public final class TracksInfo implements Bundleable {
|
||||
@IntDef({
|
||||
FIELD_TRACK_GROUP,
|
||||
FIELD_TRACK_SUPPORT,
|
||||
FIELD_TRACK_TYPE,
|
||||
FIELD_TRACK_SELECTED,
|
||||
FIELD_ADAPTIVE_SUPPORTED,
|
||||
})
|
||||
@ -233,7 +228,6 @@ public final class TracksInfo implements Bundleable {
|
||||
|
||||
private static final int FIELD_TRACK_GROUP = 0;
|
||||
private static final int FIELD_TRACK_SUPPORT = 1;
|
||||
private static final int FIELD_TRACK_TYPE = 2;
|
||||
private static final int FIELD_TRACK_SELECTED = 3;
|
||||
private static final int FIELD_ADAPTIVE_SUPPORTED = 4;
|
||||
|
||||
@ -242,7 +236,6 @@ public final class TracksInfo implements Bundleable {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putBundle(keyForField(FIELD_TRACK_GROUP), trackGroup.toBundle());
|
||||
bundle.putIntArray(keyForField(FIELD_TRACK_SUPPORT), trackSupport);
|
||||
bundle.putInt(keyForField(FIELD_TRACK_TYPE), trackType);
|
||||
bundle.putBooleanArray(keyForField(FIELD_TRACK_SELECTED), trackSelected);
|
||||
bundle.putBoolean(keyForField(FIELD_ADAPTIVE_SUPPORTED), adaptiveSupported);
|
||||
return bundle;
|
||||
@ -259,16 +252,13 @@ public final class TracksInfo implements Bundleable {
|
||||
final @C.FormatSupport int[] trackSupport =
|
||||
MoreObjects.firstNonNull(
|
||||
bundle.getIntArray(keyForField(FIELD_TRACK_SUPPORT)), new int[trackGroup.length]);
|
||||
@C.TrackType
|
||||
int trackType = bundle.getInt(keyForField(FIELD_TRACK_TYPE), C.TRACK_TYPE_UNKNOWN);
|
||||
boolean[] selected =
|
||||
MoreObjects.firstNonNull(
|
||||
bundle.getBooleanArray(keyForField(FIELD_TRACK_SELECTED)),
|
||||
new boolean[trackGroup.length]);
|
||||
boolean adaptiveSupported =
|
||||
bundle.getBoolean(keyForField(FIELD_ADAPTIVE_SUPPORTED), false);
|
||||
return new TrackGroupInfo(
|
||||
trackType, trackGroup, adaptiveSupported, trackSupport, selected);
|
||||
return new TrackGroupInfo(trackGroup, adaptiveSupported, trackSupport, selected);
|
||||
};
|
||||
|
||||
private static String keyForField(@FieldNumber int field) {
|
||||
@ -300,7 +290,7 @@ public final class TracksInfo implements Bundleable {
|
||||
/** Returns true if there are tracks of type {@code trackType}, and false otherwise. */
|
||||
public boolean hasTracksOfType(@C.TrackType int trackType) {
|
||||
for (int i = 0; i < trackGroupInfos.size(); i++) {
|
||||
if (trackGroupInfos.get(i).trackType == trackType) {
|
||||
if (trackGroupInfos.get(i).getTrackType() == trackType) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -330,7 +320,7 @@ public final class TracksInfo implements Bundleable {
|
||||
@C.TrackType int trackType, boolean allowExceedsCapabilities) {
|
||||
boolean supported = true;
|
||||
for (int i = 0; i < trackGroupInfos.size(); i++) {
|
||||
if (trackGroupInfos.get(i).trackType == trackType) {
|
||||
if (trackGroupInfos.get(i).getTrackType() == trackType) {
|
||||
if (trackGroupInfos.get(i).isSupported(allowExceedsCapabilities)) {
|
||||
return true;
|
||||
} else {
|
||||
|
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package androidx.media3.common;
|
||||
|
||||
import static androidx.media3.common.MimeTypes.AUDIO_AAC;
|
||||
import static androidx.media3.common.MimeTypes.VIDEO_H264;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import androidx.media3.common.TracksInfo.TrackGroupInfo;
|
||||
@ -40,14 +42,14 @@ public class TracksInfoTest {
|
||||
new TracksInfo(
|
||||
ImmutableList.of(
|
||||
new TrackGroupInfo(
|
||||
C.TRACK_TYPE_AUDIO,
|
||||
new TrackGroup(new Format.Builder().build()),
|
||||
new TrackGroup(new Format.Builder().setSampleMimeType(AUDIO_AAC).build()),
|
||||
/* adaptiveSupported= */ false,
|
||||
new int[] {C.FORMAT_EXCEEDS_CAPABILITIES},
|
||||
/* tracksSelected= */ new boolean[] {true}),
|
||||
new TrackGroupInfo(
|
||||
C.TRACK_TYPE_VIDEO,
|
||||
new TrackGroup(new Format.Builder().build(), new Format.Builder().build()),
|
||||
new TrackGroup(
|
||||
new Format.Builder().setSampleMimeType(VIDEO_H264).build(),
|
||||
new Format.Builder().setSampleMimeType(VIDEO_H264).build()),
|
||||
/* adaptiveSupported= */ true,
|
||||
new int[] {C.FORMAT_UNSUPPORTED_DRM, C.FORMAT_UNSUPPORTED_TYPE},
|
||||
/* tracksSelected= */ new boolean[] {false, true})));
|
||||
@ -59,7 +61,12 @@ public class TracksInfoTest {
|
||||
public void tracksInfoGetters_withoutTrack_returnExpectedValues() {
|
||||
TracksInfo tracksInfo = new TracksInfo(ImmutableList.of());
|
||||
|
||||
assertThat(tracksInfo.hasTracksOfType(C.TRACK_TYPE_AUDIO)).isFalse();
|
||||
assertThat(tracksInfo.isTypeSupportedOrEmpty(C.TRACK_TYPE_AUDIO)).isTrue();
|
||||
assertThat(
|
||||
tracksInfo.isTypeSupportedOrEmpty(
|
||||
C.TRACK_TYPE_AUDIO, /* allowExceedsCapabilities= */ true))
|
||||
.isTrue();
|
||||
assertThat(tracksInfo.isTypeSelected(C.TRACK_TYPE_AUDIO)).isFalse();
|
||||
ImmutableList<TrackGroupInfo> trackGroupInfos = tracksInfo.getTrackGroupInfos();
|
||||
assertThat(trackGroupInfos).isEmpty();
|
||||
@ -77,15 +84,15 @@ public class TracksInfoTest {
|
||||
public void tracksInfoGetters_ofComplexTracksInfo_returnExpectedValues() {
|
||||
TrackGroupInfo trackGroupInfo0 =
|
||||
new TrackGroupInfo(
|
||||
C.TRACK_TYPE_AUDIO,
|
||||
new TrackGroup(new Format.Builder().build()),
|
||||
new TrackGroup(new Format.Builder().setSampleMimeType(AUDIO_AAC).build()),
|
||||
/* adaptiveSupported= */ false,
|
||||
new int[] {C.FORMAT_EXCEEDS_CAPABILITIES},
|
||||
/* tracksSelected= */ new boolean[] {false});
|
||||
TrackGroupInfo trackGroupInfo1 =
|
||||
new TrackGroupInfo(
|
||||
C.TRACK_TYPE_VIDEO,
|
||||
new TrackGroup(new Format.Builder().build(), new Format.Builder().build()),
|
||||
new TrackGroup(
|
||||
new Format.Builder().setSampleMimeType(VIDEO_H264).build(),
|
||||
new Format.Builder().setSampleMimeType(VIDEO_H264).build()),
|
||||
/* adaptiveSupported= */ true,
|
||||
new int[] {C.FORMAT_UNSUPPORTED_DRM, C.FORMAT_HANDLED},
|
||||
/* tracksSelected= */ new boolean[] {false, true});
|
||||
@ -97,6 +104,18 @@ public class TracksInfoTest {
|
||||
assertThat(tracksInfo.isTypeSupportedOrEmpty(C.TRACK_TYPE_AUDIO)).isFalse();
|
||||
assertThat(tracksInfo.isTypeSupportedOrEmpty(C.TRACK_TYPE_VIDEO)).isTrue();
|
||||
assertThat(tracksInfo.isTypeSupportedOrEmpty(C.TRACK_TYPE_TEXT)).isTrue();
|
||||
assertThat(
|
||||
tracksInfo.isTypeSupportedOrEmpty(
|
||||
C.TRACK_TYPE_AUDIO, /* allowExceedsCapabilities= */ true))
|
||||
.isTrue();
|
||||
assertThat(
|
||||
tracksInfo.isTypeSupportedOrEmpty(
|
||||
C.TRACK_TYPE_VIDEO, /* allowExceedsCapabilities= */ true))
|
||||
.isTrue();
|
||||
assertThat(
|
||||
tracksInfo.isTypeSupportedOrEmpty(
|
||||
C.TRACK_TYPE_TEXT, /* allowExceedsCapabilities= */ true))
|
||||
.isTrue();
|
||||
assertThat(tracksInfo.isTypeSelected(C.TRACK_TYPE_AUDIO)).isFalse();
|
||||
assertThat(tracksInfo.isTypeSelected(C.TRACK_TYPE_VIDEO)).isTrue();
|
||||
ImmutableList<TrackGroupInfo> trackGroupInfos = tracksInfo.getTrackGroupInfos();
|
||||
@ -124,8 +143,7 @@ public class TracksInfoTest {
|
||||
public void trackGroupInfo_withSingleTrack_isNotAdaptive() {
|
||||
TrackGroupInfo trackGroupInfo0 =
|
||||
new TrackGroupInfo(
|
||||
C.TRACK_TYPE_AUDIO,
|
||||
new TrackGroup(new Format.Builder().build()),
|
||||
new TrackGroup(new Format.Builder().setSampleMimeType(AUDIO_AAC).build()),
|
||||
/* adaptiveSupported= */ true,
|
||||
new int[] {C.FORMAT_EXCEEDS_CAPABILITIES},
|
||||
/* tracksSelected= */ new boolean[] {false});
|
||||
|
@ -29,7 +29,6 @@ import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.C.FormatSupport;
|
||||
import androidx.media3.common.MimeTypes;
|
||||
import androidx.media3.common.Timeline;
|
||||
import androidx.media3.common.TrackGroup;
|
||||
import androidx.media3.common.TrackGroupArray;
|
||||
@ -373,8 +372,7 @@ public abstract class MappingTrackSelector extends TrackSelector {
|
||||
for (int groupIndex = 0; groupIndex < trackGroups.length; groupIndex++) {
|
||||
TrackGroup group = trackGroups.get(groupIndex);
|
||||
// Associate the group to a preferred renderer.
|
||||
boolean preferUnassociatedRenderer =
|
||||
MimeTypes.getTrackType(group.getFormat(0).sampleMimeType) == C.TRACK_TYPE_METADATA;
|
||||
boolean preferUnassociatedRenderer = group.type == C.TRACK_TYPE_METADATA;
|
||||
int rendererIndex =
|
||||
findRenderer(
|
||||
rendererCapabilities, group, rendererTrackGroupCounts, preferUnassociatedRenderer);
|
||||
@ -588,10 +586,8 @@ public abstract class MappingTrackSelector extends TrackSelector {
|
||||
&& trackSelection.indexOf(trackIndex) != C.INDEX_UNSET;
|
||||
selected[trackIndex] = isTrackSelected;
|
||||
}
|
||||
@C.TrackType int trackGroupType = mappedTrackInfo.getRendererType(rendererIndex);
|
||||
builder.add(
|
||||
new TracksInfo.TrackGroupInfo(
|
||||
trackGroupType, trackGroup, adaptiveSupported, trackSupport, selected));
|
||||
new TracksInfo.TrackGroupInfo(trackGroup, adaptiveSupported, trackSupport, selected));
|
||||
}
|
||||
}
|
||||
TrackGroupArray unmappedTrackGroups = mappedTrackInfo.getUnmappedTrackGroups();
|
||||
@ -600,12 +596,10 @@ public abstract class MappingTrackSelector extends TrackSelector {
|
||||
@C.FormatSupport int[] trackSupport = new int[trackGroup.length];
|
||||
Arrays.fill(trackSupport, C.FORMAT_UNSUPPORTED_TYPE);
|
||||
// A track group only contains tracks of the same type, thus only consider the first track.
|
||||
@C.TrackType
|
||||
int trackGroupType = MimeTypes.getTrackType(trackGroup.getFormat(0).sampleMimeType);
|
||||
boolean[] selected = new boolean[trackGroup.length]; // Initialized to false.
|
||||
builder.add(
|
||||
new TracksInfo.TrackGroupInfo(
|
||||
trackGroupType, trackGroup, /* adaptiveSupported= */ false, trackSupport, selected));
|
||||
trackGroup, /* adaptiveSupported= */ false, trackSupport, selected));
|
||||
}
|
||||
return new TracksInfo(builder.build());
|
||||
}
|
||||
|
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package androidx.media3.exoplayer.trackselection;
|
||||
|
||||
import static androidx.media3.common.MimeTypes.AUDIO_AAC;
|
||||
import static androidx.media3.common.MimeTypes.VIDEO_H264;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.util.Pair;
|
||||
@ -53,7 +55,7 @@ public final class MappingTrackSelectorTest {
|
||||
new FakeRendererCapabilities(C.TRACK_TYPE_METADATA);
|
||||
|
||||
private static final TrackGroup VIDEO_TRACK_GROUP = buildTrackGroup(MimeTypes.VIDEO_H264);
|
||||
private static final TrackGroup AUDIO_TRACK_GROUP = buildTrackGroup(MimeTypes.AUDIO_AAC);
|
||||
private static final TrackGroup AUDIO_TRACK_GROUP = buildTrackGroup(AUDIO_AAC);
|
||||
private static final TrackGroup METADATA_TRACK_GROUP = buildTrackGroup(MimeTypes.APPLICATION_ID3);
|
||||
|
||||
private static final Timeline TIMELINE = new FakeTimeline();
|
||||
@ -146,10 +148,13 @@ public final class MappingTrackSelectorTest {
|
||||
new int[] {C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_VIDEO},
|
||||
new TrackGroupArray[] {
|
||||
new TrackGroupArray(
|
||||
new TrackGroup("0", new Format.Builder().build()),
|
||||
new TrackGroup("1", new Format.Builder().build())),
|
||||
new TrackGroup("0", new Format.Builder().setSampleMimeType(AUDIO_AAC).build()),
|
||||
new TrackGroup("1", new Format.Builder().setSampleMimeType(AUDIO_AAC).build())),
|
||||
new TrackGroupArray(
|
||||
new TrackGroup("2", new Format.Builder().build(), new Format.Builder().build()))
|
||||
new TrackGroup(
|
||||
"2",
|
||||
new Format.Builder().setSampleMimeType(VIDEO_H264).build(),
|
||||
new Format.Builder().setSampleMimeType(VIDEO_H264).build()))
|
||||
},
|
||||
new int[] {
|
||||
RendererCapabilities.ADAPTIVE_SEAMLESS, RendererCapabilities.ADAPTIVE_NOT_SUPPORTED
|
||||
|
Loading…
x
Reference in New Issue
Block a user