diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/offline/DownloadHelper.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/offline/DownloadHelper.java index 4aabd38c40..41fb472684 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/offline/DownloadHelper.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/offline/DownloadHelper.java @@ -34,6 +34,7 @@ import androidx.media3.common.TrackGroup; import androidx.media3.common.TrackGroupArray; import androidx.media3.common.TrackSelectionOverride; import androidx.media3.common.TrackSelectionParameters; +import androidx.media3.common.TracksInfo; import androidx.media3.common.util.Assertions; import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.Util; @@ -58,6 +59,7 @@ import androidx.media3.exoplayer.trackselection.DefaultTrackSelector; import androidx.media3.exoplayer.trackselection.DefaultTrackSelector.SelectionOverride; import androidx.media3.exoplayer.trackselection.ExoTrackSelection; import androidx.media3.exoplayer.trackselection.MappingTrackSelector.MappedTrackInfo; +import androidx.media3.exoplayer.trackselection.TrackSelectionUtil; import androidx.media3.exoplayer.trackselection.TrackSelectorResult; import androidx.media3.exoplayer.upstream.Allocator; import androidx.media3.exoplayer.upstream.BandwidthMeter; @@ -543,6 +545,20 @@ public final class DownloadHelper { return trackGroupArrays.length; } + /** + * Returns {@link TracksInfo} for the given period. Must not be called until after preparation + * completes. + * + * @param periodIndex The period index. + * @return The {@link TracksInfo} for the period. May be {@link TracksInfo#EMPTY} for single + * stream content. + */ + public TracksInfo getTracksInfo(int periodIndex) { + assertPreparedWithMedia(); + return TrackSelectionUtil.buildTracksInfo( + mappedTrackInfos[periodIndex], immutableTrackSelectionsByPeriodAndRenderer[periodIndex]); + } + /** * Returns the track groups for the given period. Must not be called until after preparation * completes. diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/trackselection/MappingTrackSelector.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/trackselection/MappingTrackSelector.java index 5f031720de..233ac0497d 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/trackselection/MappingTrackSelector.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/trackselection/MappingTrackSelector.java @@ -32,7 +32,6 @@ import androidx.media3.common.C.FormatSupport; import androidx.media3.common.Timeline; import androidx.media3.common.TrackGroup; import androidx.media3.common.TrackGroupArray; -import androidx.media3.common.TrackSelection; import androidx.media3.common.TracksInfo; import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.Util; @@ -43,7 +42,6 @@ import androidx.media3.exoplayer.RendererCapabilities.AdaptiveSupport; import androidx.media3.exoplayer.RendererCapabilities.Capabilities; import androidx.media3.exoplayer.RendererConfiguration; import androidx.media3.exoplayer.source.MediaSource.MediaPeriodId; -import com.google.common.collect.ImmutableList; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -429,7 +427,7 @@ public abstract class MappingTrackSelector extends TrackSelector { periodId, timeline); - TracksInfo tracksInfo = buildTracksInfo(result.second, mappedTrackInfo); + TracksInfo tracksInfo = TrackSelectionUtil.buildTracksInfo(mappedTrackInfo, result.second); return new TrackSelectorResult(result.first, result.second, tracksInfo, mappedTrackInfo); } @@ -559,48 +557,4 @@ public abstract class MappingTrackSelector extends TrackSelector { } return mixedMimeTypeAdaptationSupport; } - - @VisibleForTesting - /* package */ static TracksInfo buildTracksInfo( - @NullableType TrackSelection[] selections, MappedTrackInfo mappedTrackInfo) { - ImmutableList.Builder builder = new ImmutableList.Builder<>(); - for (int rendererIndex = 0; - rendererIndex < mappedTrackInfo.getRendererCount(); - rendererIndex++) { - TrackGroupArray trackGroupArray = mappedTrackInfo.getTrackGroups(rendererIndex); - @Nullable TrackSelection trackSelection = selections[rendererIndex]; - for (int groupIndex = 0; groupIndex < trackGroupArray.length; groupIndex++) { - TrackGroup trackGroup = trackGroupArray.get(groupIndex); - boolean adaptiveSupported = - mappedTrackInfo.getAdaptiveSupport( - rendererIndex, groupIndex, /* includeCapabilitiesExceededTracks= */ false) - != RendererCapabilities.ADAPTIVE_NOT_SUPPORTED; - @C.FormatSupport int[] trackSupport = new int[trackGroup.length]; - boolean[] selected = new boolean[trackGroup.length]; - for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) { - trackSupport[trackIndex] = - mappedTrackInfo.getTrackSupport(rendererIndex, groupIndex, trackIndex); - boolean isTrackSelected = - trackSelection != null - && trackSelection.getTrackGroup().equals(trackGroup) - && trackSelection.indexOf(trackIndex) != C.INDEX_UNSET; - selected[trackIndex] = isTrackSelected; - } - builder.add( - new TracksInfo.TrackGroupInfo(trackGroup, adaptiveSupported, trackSupport, selected)); - } - } - TrackGroupArray unmappedTrackGroups = mappedTrackInfo.getUnmappedTrackGroups(); - for (int groupIndex = 0; groupIndex < unmappedTrackGroups.length; groupIndex++) { - TrackGroup trackGroup = unmappedTrackGroups.get(groupIndex); - @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. - boolean[] selected = new boolean[trackGroup.length]; // Initialized to false. - builder.add( - new TracksInfo.TrackGroupInfo( - trackGroup, /* adaptiveSupported= */ false, trackSupport, selected)); - } - return new TracksInfo(builder.build()); - } } diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/trackselection/TrackSelectionUtil.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/trackselection/TrackSelectionUtil.java index 9c78ae31ca..ed62fa7e63 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/trackselection/TrackSelectionUtil.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/trackselection/TrackSelectionUtil.java @@ -17,11 +17,20 @@ package androidx.media3.exoplayer.trackselection; import android.os.SystemClock; import androidx.annotation.Nullable; +import androidx.media3.common.C; +import androidx.media3.common.TrackGroup; import androidx.media3.common.TrackGroupArray; +import androidx.media3.common.TrackSelection; +import androidx.media3.common.TracksInfo; +import androidx.media3.common.TracksInfo.TrackGroupInfo; import androidx.media3.common.util.UnstableApi; +import androidx.media3.exoplayer.RendererCapabilities; import androidx.media3.exoplayer.trackselection.DefaultTrackSelector.SelectionOverride; import androidx.media3.exoplayer.trackselection.ExoTrackSelection.Definition; import androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy; +import com.google.common.collect.ImmutableList; +import java.util.Arrays; +import java.util.List; import org.checkerframework.checker.nullness.compatqual.NullableType; /** Track selection related utility methods. */ @@ -126,4 +135,81 @@ public final class TrackSelectionUtil { numberOfTracks, numberOfExcludedTracks); } + + /** + * Returns {@link TracksInfo} built from {@link MappingTrackSelector.MappedTrackInfo} and {@link + * TrackSelection TrackSelections} for each renderer. + * + * @param mappedTrackInfo The {@link MappingTrackSelector.MappedTrackInfo} + * @param selections The track selections, indexed by renderer. A null entry indicates that a + * renderer does not have any selected tracks. + * @return The corresponding {@link TracksInfo}. + */ + @SuppressWarnings({"unchecked", "rawtypes"}) // Initialization of array of Lists. + public static TracksInfo buildTracksInfo( + MappingTrackSelector.MappedTrackInfo mappedTrackInfo, + @NullableType TrackSelection[] selections) { + List[] listSelections = new List[selections.length]; + for (int i = 0; i < selections.length; i++) { + @Nullable TrackSelection selection = selections[i]; + listSelections[i] = selection != null ? ImmutableList.of(selection) : ImmutableList.of(); + } + return buildTracksInfo(mappedTrackInfo, listSelections); + } + + /** + * Returns {@link TracksInfo} built from {@link MappingTrackSelector.MappedTrackInfo} and {@link + * TrackSelection TrackSelections} for each renderer. + * + * @param mappedTrackInfo The {@link MappingTrackSelector.MappedTrackInfo} + * @param selections The track selections, indexed by renderer. Null entries are not permitted. An + * empty list indicates that a renderer does not have any selected tracks. + * @return The corresponding {@link TracksInfo}. + */ + public static TracksInfo buildTracksInfo( + MappingTrackSelector.MappedTrackInfo mappedTrackInfo, + List[] selections) { + ImmutableList.Builder trackGroupInfos = new ImmutableList.Builder<>(); + for (int rendererIndex = 0; + rendererIndex < mappedTrackInfo.getRendererCount(); + rendererIndex++) { + TrackGroupArray trackGroupArray = mappedTrackInfo.getTrackGroups(rendererIndex); + List rendererTrackSelections = selections[rendererIndex]; + for (int groupIndex = 0; groupIndex < trackGroupArray.length; groupIndex++) { + TrackGroup trackGroup = trackGroupArray.get(groupIndex); + boolean adaptiveSupported = + mappedTrackInfo.getAdaptiveSupport( + rendererIndex, groupIndex, /* includeCapabilitiesExceededTracks= */ false) + != RendererCapabilities.ADAPTIVE_NOT_SUPPORTED; + @C.FormatSupport int[] trackSupport = new int[trackGroup.length]; + boolean[] selected = new boolean[trackGroup.length]; + for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) { + trackSupport[trackIndex] = + mappedTrackInfo.getTrackSupport(rendererIndex, groupIndex, trackIndex); + boolean isTrackSelected = false; + for (int i = 0; i < rendererTrackSelections.size(); i++) { + TrackSelection trackSelection = rendererTrackSelections.get(i); + if (trackSelection.getTrackGroup().equals(trackGroup) + && trackSelection.indexOf(trackIndex) != C.INDEX_UNSET) { + isTrackSelected = true; + break; + } + } + selected[trackIndex] = isTrackSelected; + } + trackGroupInfos.add( + new TrackGroupInfo(trackGroup, adaptiveSupported, trackSupport, selected)); + } + } + TrackGroupArray unmappedTrackGroups = mappedTrackInfo.getUnmappedTrackGroups(); + for (int groupIndex = 0; groupIndex < unmappedTrackGroups.length; groupIndex++) { + TrackGroup trackGroup = unmappedTrackGroups.get(groupIndex); + @C.FormatSupport int[] trackSupport = new int[trackGroup.length]; + Arrays.fill(trackSupport, C.FORMAT_UNSUPPORTED_TYPE); + boolean[] selected = new boolean[trackGroup.length]; + trackGroupInfos.add( + new TrackGroupInfo(trackGroup, /* adaptiveSupported= */ false, trackSupport, selected)); + } + return new TracksInfo(trackGroupInfos.build()); + } } diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/trackselection/MappingTrackSelectorTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/trackselection/MappingTrackSelectorTest.java index 6badef1484..c4ec0a178a 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/trackselection/MappingTrackSelectorTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/trackselection/MappingTrackSelectorTest.java @@ -16,7 +16,6 @@ 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; @@ -26,9 +25,6 @@ import androidx.media3.common.MimeTypes; import androidx.media3.common.Timeline; import androidx.media3.common.TrackGroup; import androidx.media3.common.TrackGroupArray; -import androidx.media3.common.TrackSelection; -import androidx.media3.common.TracksInfo; -import androidx.media3.common.TracksInfo.TrackGroupInfo; import androidx.media3.common.util.Util; import androidx.media3.exoplayer.ExoPlaybackException; import androidx.media3.exoplayer.RendererCapabilities; @@ -38,7 +34,6 @@ import androidx.media3.exoplayer.RendererConfiguration; import androidx.media3.exoplayer.source.MediaSource.MediaPeriodId; import androidx.media3.test.utils.FakeTimeline; import androidx.test.ext.junit.runners.AndroidJUnit4; -import com.google.common.collect.ImmutableList; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; @@ -140,64 +135,6 @@ public final class MappingTrackSelectorTest { return new TrackGroup(new Format.Builder().setSampleMimeType(sampleMimeType).build()); } - @Test - public void buildTrackInfos_withTestValues_isAsExpected() { - MappingTrackSelector.MappedTrackInfo mappedTrackInfo = - new MappingTrackSelector.MappedTrackInfo( - new String[] {"1", "2"}, - new int[] {C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_VIDEO}, - new TrackGroupArray[] { - new TrackGroupArray( - 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().setSampleMimeType(VIDEO_H264).build(), - new Format.Builder().setSampleMimeType(VIDEO_H264).build())) - }, - new int[] { - RendererCapabilities.ADAPTIVE_SEAMLESS, RendererCapabilities.ADAPTIVE_NOT_SUPPORTED - }, - new int[][][] { - new int[][] {new int[] {C.FORMAT_HANDLED}, new int[] {C.FORMAT_UNSUPPORTED_SUBTYPE}}, - new int[][] {new int[] {C.FORMAT_UNSUPPORTED_DRM, C.FORMAT_EXCEEDS_CAPABILITIES}} - }, - new TrackGroupArray(new TrackGroup(new Format.Builder().build()))); - TrackSelection[] selections = - new TrackSelection[] { - new FixedTrackSelection(mappedTrackInfo.getTrackGroups(0).get(1), 0), - new FixedTrackSelection(mappedTrackInfo.getTrackGroups(1).get(0), 1) - }; - - TracksInfo tracksInfo = MappingTrackSelector.buildTracksInfo(selections, mappedTrackInfo); - - ImmutableList trackGroupInfos = tracksInfo.getTrackGroupInfos(); - assertThat(trackGroupInfos).hasSize(4); - assertThat(trackGroupInfos.get(0).getTrackGroup()) - .isEqualTo(mappedTrackInfo.getTrackGroups(0).get(0)); - assertThat(trackGroupInfos.get(1).getTrackGroup()) - .isEqualTo(mappedTrackInfo.getTrackGroups(0).get(1)); - assertThat(trackGroupInfos.get(2).getTrackGroup()) - .isEqualTo(mappedTrackInfo.getTrackGroups(1).get(0)); - assertThat(trackGroupInfos.get(3).getTrackGroup()) - .isEqualTo(mappedTrackInfo.getUnmappedTrackGroups().get(0)); - assertThat(trackGroupInfos.get(0).getTrackSupport(0)).isEqualTo(C.FORMAT_HANDLED); - assertThat(trackGroupInfos.get(1).getTrackSupport(0)).isEqualTo(C.FORMAT_UNSUPPORTED_SUBTYPE); - assertThat(trackGroupInfos.get(2).getTrackSupport(0)).isEqualTo(C.FORMAT_UNSUPPORTED_DRM); - assertThat(trackGroupInfos.get(2).getTrackSupport(1)).isEqualTo(C.FORMAT_EXCEEDS_CAPABILITIES); - assertThat(trackGroupInfos.get(3).getTrackSupport(0)).isEqualTo(C.FORMAT_UNSUPPORTED_TYPE); - assertThat(trackGroupInfos.get(0).isTrackSelected(0)).isFalse(); - assertThat(trackGroupInfos.get(1).isTrackSelected(0)).isTrue(); - assertThat(trackGroupInfos.get(2).isTrackSelected(0)).isFalse(); - assertThat(trackGroupInfos.get(2).isTrackSelected(1)).isTrue(); - assertThat(trackGroupInfos.get(3).isTrackSelected(0)).isFalse(); - assertThat(trackGroupInfos.get(0).getTrackType()).isEqualTo(C.TRACK_TYPE_AUDIO); - assertThat(trackGroupInfos.get(1).getTrackType()).isEqualTo(C.TRACK_TYPE_AUDIO); - assertThat(trackGroupInfos.get(2).getTrackType()).isEqualTo(C.TRACK_TYPE_VIDEO); - assertThat(trackGroupInfos.get(3).getTrackType()).isEqualTo(C.TRACK_TYPE_UNKNOWN); - } - /** * A {@link MappingTrackSelector} that stashes the {@link MappedTrackInfo} passed to {@link * #selectTracks(MappedTrackInfo, int[][][], int[], MediaPeriodId, Timeline)}. diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/trackselection/TrackSelectionUtilTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/trackselection/TrackSelectionUtilTest.java new file mode 100644 index 0000000000..99cd8bb32a --- /dev/null +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/trackselection/TrackSelectionUtilTest.java @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2021 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 androidx.media3.common.C.FORMAT_EXCEEDS_CAPABILITIES; +import static androidx.media3.common.C.FORMAT_HANDLED; +import static androidx.media3.common.C.FORMAT_UNSUPPORTED_DRM; +import static androidx.media3.common.C.FORMAT_UNSUPPORTED_SUBTYPE; +import static androidx.media3.common.C.FORMAT_UNSUPPORTED_TYPE; +import static androidx.media3.common.C.TRACK_TYPE_AUDIO; +import static androidx.media3.common.C.TRACK_TYPE_UNKNOWN; +import static androidx.media3.common.C.TRACK_TYPE_VIDEO; +import static androidx.media3.common.MimeTypes.AUDIO_AAC; +import static androidx.media3.common.MimeTypes.AUDIO_OPUS; +import static androidx.media3.common.MimeTypes.VIDEO_H264; +import static androidx.media3.exoplayer.RendererCapabilities.ADAPTIVE_NOT_SUPPORTED; +import static androidx.media3.exoplayer.RendererCapabilities.ADAPTIVE_SEAMLESS; +import static com.google.common.truth.Truth.assertThat; + +import androidx.media3.common.Format; +import androidx.media3.common.TrackGroup; +import androidx.media3.common.TrackGroupArray; +import androidx.media3.common.TrackSelection; +import androidx.media3.common.TracksInfo; +import androidx.media3.common.TracksInfo.TrackGroupInfo; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import com.google.common.collect.ImmutableList; +import java.util.List; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** Unit tests for {@link TrackSelectionUtil}. */ +@RunWith(AndroidJUnit4.class) +public class TrackSelectionUtilTest { + + @Test + public void buildTrackInfos_withTestValues_isAsExpected() { + MappingTrackSelector.MappedTrackInfo mappedTrackInfo = + new MappingTrackSelector.MappedTrackInfo( + new String[] {"rendererName1", "rendererName2"}, + new int[] {TRACK_TYPE_AUDIO, TRACK_TYPE_VIDEO}, + new TrackGroupArray[] { + new TrackGroupArray( + new TrackGroup("0", new Format.Builder().setSampleMimeType(AUDIO_AAC).build()), + new TrackGroup("1", new Format.Builder().setSampleMimeType(AUDIO_OPUS).build())), + new TrackGroupArray( + new TrackGroup( + "2", + new Format.Builder().setSampleMimeType(VIDEO_H264).build(), + new Format.Builder().setSampleMimeType(VIDEO_H264).build())) + }, + new int[] {ADAPTIVE_SEAMLESS, ADAPTIVE_NOT_SUPPORTED}, + new int[][][] { + new int[][] {new int[] {FORMAT_HANDLED}, new int[] {FORMAT_UNSUPPORTED_SUBTYPE}}, + new int[][] {new int[] {FORMAT_UNSUPPORTED_DRM, FORMAT_EXCEEDS_CAPABILITIES}} + }, + new TrackGroupArray(new TrackGroup(new Format.Builder().build()))); + TrackSelection[] selections = + new TrackSelection[] { + new FixedTrackSelection(mappedTrackInfo.getTrackGroups(0).get(1), 0), + new FixedTrackSelection(mappedTrackInfo.getTrackGroups(1).get(0), 1) + }; + + TracksInfo tracksInfo = TrackSelectionUtil.buildTracksInfo(mappedTrackInfo, selections); + + ImmutableList trackGroupInfos = tracksInfo.getTrackGroupInfos(); + assertThat(trackGroupInfos).hasSize(4); + assertThat(trackGroupInfos.get(0).getTrackGroup()) + .isEqualTo(mappedTrackInfo.getTrackGroups(0).get(0)); + assertThat(trackGroupInfos.get(1).getTrackGroup()) + .isEqualTo(mappedTrackInfo.getTrackGroups(0).get(1)); + assertThat(trackGroupInfos.get(2).getTrackGroup()) + .isEqualTo(mappedTrackInfo.getTrackGroups(1).get(0)); + assertThat(trackGroupInfos.get(3).getTrackGroup()) + .isEqualTo(mappedTrackInfo.getUnmappedTrackGroups().get(0)); + assertThat(trackGroupInfos.get(0).getTrackSupport(0)).isEqualTo(FORMAT_HANDLED); + assertThat(trackGroupInfos.get(1).getTrackSupport(0)).isEqualTo(FORMAT_UNSUPPORTED_SUBTYPE); + assertThat(trackGroupInfos.get(2).getTrackSupport(0)).isEqualTo(FORMAT_UNSUPPORTED_DRM); + assertThat(trackGroupInfos.get(2).getTrackSupport(1)).isEqualTo(FORMAT_EXCEEDS_CAPABILITIES); + assertThat(trackGroupInfos.get(3).getTrackSupport(0)).isEqualTo(FORMAT_UNSUPPORTED_TYPE); + assertThat(trackGroupInfos.get(0).isTrackSelected(0)).isFalse(); + assertThat(trackGroupInfos.get(1).isTrackSelected(0)).isTrue(); + assertThat(trackGroupInfos.get(2).isTrackSelected(0)).isFalse(); + assertThat(trackGroupInfos.get(2).isTrackSelected(1)).isTrue(); + assertThat(trackGroupInfos.get(3).isTrackSelected(0)).isFalse(); + assertThat(trackGroupInfos.get(0).getTrackType()).isEqualTo(TRACK_TYPE_AUDIO); + assertThat(trackGroupInfos.get(1).getTrackType()).isEqualTo(TRACK_TYPE_AUDIO); + assertThat(trackGroupInfos.get(2).getTrackType()).isEqualTo(TRACK_TYPE_VIDEO); + assertThat(trackGroupInfos.get(3).getTrackType()).isEqualTo(TRACK_TYPE_UNKNOWN); + } + + @Test + @SuppressWarnings({"unchecked", "rawtypes"}) // Initialization of array of Lists. + public void buildTrackInfos_withMultipleSelectionForRenderer_isAsExpected() { + MappingTrackSelector.MappedTrackInfo mappedTrackInfo = + new MappingTrackSelector.MappedTrackInfo( + new String[] {"rendererName1", "rendererName2"}, + new int[] {TRACK_TYPE_AUDIO, TRACK_TYPE_VIDEO}, + new TrackGroupArray[] { + new TrackGroupArray( + new TrackGroup("0", new Format.Builder().setSampleMimeType(AUDIO_AAC).build()), + new TrackGroup( + "1", + new Format.Builder().setSampleMimeType(AUDIO_OPUS).setSampleRate(1).build(), + new Format.Builder().setSampleMimeType(AUDIO_OPUS).setSampleRate(2).build())), + new TrackGroupArray() + }, + new int[] {ADAPTIVE_SEAMLESS, ADAPTIVE_SEAMLESS}, + new int[][][] { + new int[][] {new int[] {FORMAT_HANDLED}, new int[] {FORMAT_HANDLED, FORMAT_HANDLED}}, + new int[][] {new int[0]} + }, + new TrackGroupArray()); + + List[] selections = + new List[] { + ImmutableList.of( + new FixedTrackSelection(mappedTrackInfo.getTrackGroups(0).get(0), 0), + new FixedTrackSelection(mappedTrackInfo.getTrackGroups(0).get(1), 1)), + ImmutableList.of() + }; + + TracksInfo tracksInfo = TrackSelectionUtil.buildTracksInfo(mappedTrackInfo, selections); + + ImmutableList trackGroupInfos = tracksInfo.getTrackGroupInfos(); + assertThat(trackGroupInfos).hasSize(2); + assertThat(trackGroupInfos.get(0).getTrackGroup()) + .isEqualTo(mappedTrackInfo.getTrackGroups(0).get(0)); + assertThat(trackGroupInfos.get(1).getTrackGroup()) + .isEqualTo(mappedTrackInfo.getTrackGroups(0).get(1)); + assertThat(trackGroupInfos.get(0).getTrackSupport(0)).isEqualTo(FORMAT_HANDLED); + assertThat(trackGroupInfos.get(1).getTrackSupport(0)).isEqualTo(FORMAT_HANDLED); + assertThat(trackGroupInfos.get(1).getTrackSupport(1)).isEqualTo(FORMAT_HANDLED); + assertThat(trackGroupInfos.get(0).isTrackSelected(0)).isTrue(); + assertThat(trackGroupInfos.get(1).isTrackSelected(0)).isFalse(); + assertThat(trackGroupInfos.get(1).isTrackSelected(1)).isTrue(); + assertThat(trackGroupInfos.get(0).getTrackType()).isEqualTo(TRACK_TYPE_AUDIO); + assertThat(trackGroupInfos.get(1).getTrackType()).isEqualTo(TRACK_TYPE_AUDIO); + } +}