Commit 327ec97e by tonihei

Reorder adaptive video track preferences.

This change moves the video track selection to the generic
selection method introcuced for audio and text. This ensures
we can apply the same criteria for fixed and adaptive video
track selections. Implicitly, this reorders the preferences
for adaptive tracks to give non-quality preferences (like
preferred MIME type or preferred role flags) a higher priority
than number of tracks in the selection.

Issue: google/ExoPlayer#9519
PiperOrigin-RevId: 422310902
parent 3f47da1f
...@@ -31,6 +31,9 @@ ...@@ -31,6 +31,9 @@
* Disable automatic speed adjustment for live streams that neither have * Disable automatic speed adjustment for live streams that neither have
low-latency features nor a user request setting the speed low-latency features nor a user request setting the speed
((#9329)[https://github.com/google/ExoPlayer/issues/9329]). ((#9329)[https://github.com/google/ExoPlayer/issues/9329]).
* Update video track selection logic to take preferred MIME types and role
flags into account when selecting multiple video tracks for adaptation
((#9519)[https://github.com/google/ExoPlayer/issues/9519]).
* Android 12 compatibility: * Android 12 compatibility:
* Upgrade the Cast extension to depend on * Upgrade the Cast extension to depend on
`com.google.android.gms:play-services-cast-framework:20.1.0`. Earlier `com.google.android.gms:play-services-cast-framework:20.1.0`. Earlier
......
...@@ -1859,11 +1859,17 @@ public final class DefaultTrackSelectorTest { ...@@ -1859,11 +1859,17 @@ public final class DefaultTrackSelectorTest {
throws Exception { throws Exception {
Format formatAv1 = new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_AV1).build(); Format formatAv1 = new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_AV1).build();
Format formatVp9 = new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_VP9).build(); Format formatVp9 = new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_VP9).build();
Format formatH264 = new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_H264).build(); Format formatH264Low =
TrackGroupArray trackGroups = wrapFormats(formatAv1, formatVp9, formatH264); new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_H264).setAverageBitrate(400).build();
Format formatH264High =
new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_H264).setAverageBitrate(800).build();
// Use an adaptive group to check that MIME type has a higher priority than number of tracks.
TrackGroup adaptiveGroup = new TrackGroup(formatH264Low, formatH264High);
TrackGroupArray trackGroups =
new TrackGroupArray(new TrackGroup(formatAv1), new TrackGroup(formatVp9), adaptiveGroup);
trackSelector.setParameters( trackSelector.setParameters(
trackSelector.buildUponParameters().setPreferredVideoMimeType(MimeTypes.VIDEO_VP9)); defaultParameters.buildUpon().setPreferredVideoMimeType(MimeTypes.VIDEO_VP9));
TrackSelectorResult result = TrackSelectorResult result =
trackSelector.selectTracks( trackSelector.selectTracks(
new RendererCapabilities[] {VIDEO_CAPABILITIES}, trackGroups, periodId, TIMELINE); new RendererCapabilities[] {VIDEO_CAPABILITIES}, trackGroups, periodId, TIMELINE);
...@@ -1871,8 +1877,8 @@ public final class DefaultTrackSelectorTest { ...@@ -1871,8 +1877,8 @@ public final class DefaultTrackSelectorTest {
assertFixedSelection(result.selections[0], trackGroups, formatVp9); assertFixedSelection(result.selections[0], trackGroups, formatVp9);
trackSelector.setParameters( trackSelector.setParameters(
trackSelector defaultParameters
.buildUponParameters() .buildUpon()
.setPreferredVideoMimeTypes(MimeTypes.VIDEO_VP9, MimeTypes.VIDEO_AV1)); .setPreferredVideoMimeTypes(MimeTypes.VIDEO_VP9, MimeTypes.VIDEO_AV1));
result = result =
trackSelector.selectTracks( trackSelector.selectTracks(
...@@ -1881,23 +1887,22 @@ public final class DefaultTrackSelectorTest { ...@@ -1881,23 +1887,22 @@ public final class DefaultTrackSelectorTest {
assertFixedSelection(result.selections[0], trackGroups, formatVp9); assertFixedSelection(result.selections[0], trackGroups, formatVp9);
trackSelector.setParameters( trackSelector.setParameters(
trackSelector defaultParameters
.buildUponParameters() .buildUpon()
.setPreferredVideoMimeTypes(MimeTypes.VIDEO_DIVX, MimeTypes.VIDEO_H264)); .setPreferredVideoMimeTypes(MimeTypes.VIDEO_DIVX, MimeTypes.VIDEO_H264));
result = result =
trackSelector.selectTracks( trackSelector.selectTracks(
new RendererCapabilities[] {VIDEO_CAPABILITIES}, trackGroups, periodId, TIMELINE); new RendererCapabilities[] {VIDEO_CAPABILITIES}, trackGroups, periodId, TIMELINE);
assertThat(result.length).isEqualTo(1); assertThat(result.length).isEqualTo(1);
assertFixedSelection(result.selections[0], trackGroups, formatH264); assertAdaptiveSelection(result.selections[0], adaptiveGroup, /* expectedTracks...= */ 1, 0);
// Select first in the list if no preference is specified. // Select default (=most tracks) if no preference is specified.
trackSelector.setParameters( trackSelector.setParameters(defaultParameters.buildUpon().setPreferredVideoMimeType(null));
trackSelector.buildUponParameters().setPreferredVideoMimeType(null));
result = result =
trackSelector.selectTracks( trackSelector.selectTracks(
new RendererCapabilities[] {VIDEO_CAPABILITIES}, trackGroups, periodId, TIMELINE); new RendererCapabilities[] {VIDEO_CAPABILITIES}, trackGroups, periodId, TIMELINE);
assertThat(result.length).isEqualTo(1); assertThat(result.length).isEqualTo(1);
assertFixedSelection(result.selections[0], trackGroups, formatAv1); assertAdaptiveSelection(result.selections[0], adaptiveGroup, /* expectedTracks...= */ 1, 0);
} }
/** /**
...@@ -1907,13 +1912,18 @@ public final class DefaultTrackSelectorTest { ...@@ -1907,13 +1912,18 @@ public final class DefaultTrackSelectorTest {
@Test @Test
public void selectTracks_withPreferredVideoRoleFlags_selectPreferredTrack() throws Exception { public void selectTracks_withPreferredVideoRoleFlags_selectPreferredTrack() throws Exception {
Format.Builder formatBuilder = VIDEO_FORMAT.buildUpon(); Format.Builder formatBuilder = VIDEO_FORMAT.buildUpon();
Format noRoleFlags = formatBuilder.build(); Format noRoleFlagsLow = formatBuilder.setAverageBitrate(4000).build();
Format noRoleFlagsHigh = formatBuilder.setAverageBitrate(8000).build();
Format lessRoleFlags = formatBuilder.setRoleFlags(C.ROLE_FLAG_CAPTION).build(); Format lessRoleFlags = formatBuilder.setRoleFlags(C.ROLE_FLAG_CAPTION).build();
Format moreRoleFlags = Format moreRoleFlags =
formatBuilder formatBuilder
.setRoleFlags(C.ROLE_FLAG_CAPTION | C.ROLE_FLAG_COMMENTARY | C.ROLE_FLAG_DUB) .setRoleFlags(C.ROLE_FLAG_CAPTION | C.ROLE_FLAG_COMMENTARY | C.ROLE_FLAG_DUB)
.build(); .build();
TrackGroupArray trackGroups = wrapFormats(noRoleFlags, moreRoleFlags, lessRoleFlags); // Use an adaptive group to check that role flags have higher priority than number of tracks.
TrackGroup adaptiveNoRoleFlagsGroup = new TrackGroup(noRoleFlagsLow, noRoleFlagsHigh);
TrackGroupArray trackGroups =
new TrackGroupArray(
adaptiveNoRoleFlagsGroup, new TrackGroup(moreRoleFlags), new TrackGroup(lessRoleFlags));
trackSelector.setParameters( trackSelector.setParameters(
defaultParameters defaultParameters
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment