Add preferredVideoRoleFlags to TrackSelectionParameters.

And also tweak existing role flag logic to strictly prefer perfect
matches over partial matches.

Caveat: Video role flags only supported for fixed track selections
(same issue as Issue: google/ExoPlayer#9519).

Issue: google/ExoPlayer#9402
PiperOrigin-RevId: 412292835
This commit is contained in:
tonihei 2021-11-25 17:01:15 +00:00 committed by kim-vde
parent e846e9f06c
commit 339d99b860
4 changed files with 192 additions and 56 deletions

View file

@ -2,6 +2,9 @@
### dev-v2 (not yet released)
* Core library:
* Support preferred video role flags in track selection
((#9402)[https://github.com/google/ExoPlayer/issues/9402]).
* DRM:
* Remove `playbackLooper` from `DrmSessionManager.(pre)acquireSession`.
When a `DrmSessionManager` is used by an app in a custom `MediaSource`,
@ -545,8 +548,8 @@
* The most used methods of `Player`'s audio, video, text and metadata
components have been added directly to `Player`.
* Add `Player.getAvailableCommands`, `Player.isCommandAvailable` and
`Listener.onAvailableCommandsChanged` to query which commands
that can be executed on the player.
`Listener.onAvailableCommandsChanged` to query which commands that can
be executed on the player.
* Add a `Player.Listener` interface to receive all player events.
Component listeners and `EventListener` have been deprecated.
* Add `Player.getMediaMetadata`, which returns a combined and structured
@ -555,8 +558,8 @@
* `Player.setPlaybackParameters` no longer accepts null, use
`PlaybackParameters.DEFAULT` instead.
* Report information about the old and the new playback positions to
`Listener.onPositionDiscontinuity`. Add `DISCONTINUITY_REASON_SKIP`
and `DISCONTINUITY_REASON_REMOVE` as discontinuity reasons, and rename
`Listener.onPositionDiscontinuity`. Add `DISCONTINUITY_REASON_SKIP` and
`DISCONTINUITY_REASON_REMOVE` as discontinuity reasons, and rename
`DISCONTINUITY_REASON_PERIOD_TRANSITION` to
`DISCONTINUITY_REASON_AUTO_TRANSITION`. Remove
`DISCONTINUITY_REASON_AD_INSERTION`, for which
@ -611,8 +614,8 @@
dispatched for each track in each period.
* Include the session state in DRM session-acquired listener methods.
* UI:
* Add `PlayerNotificationManager.Builder`, with the ability to
specify which group the notification should belong to.
* Add `PlayerNotificationManager.Builder`, with the ability to specify
which group the notification should belong to.
* Remove `setUseSensorRotation` from `PlayerView` and `StyledPlayerView`.
Instead, cast the view returned by `getVideoSurfaceView` to
`SphericalGLSurfaceView`, and then call `setUseSensorRotation` on the
@ -684,7 +687,8 @@
### 2.13.3 (2021-04-14)
* Published via the Google Maven repository (i.e., google()) rather than JCenter.
* Published via the Google Maven repository (i.e., google()) rather than
JCenter.
* Core:
* Reset playback speed when live playback speed control becomes unused
([#8664](https://github.com/google/ExoPlayer/issues/8664)).
@ -839,8 +843,8 @@
* Remove `Player.setVideoDecoderOutputBufferRenderer` from Player API. Use
`setVideoSurfaceView` and `clearVideoSurfaceView` instead.
* Default `SingleSampleMediaSource.treatLoadErrorsAsEndOfStream` to `true`
so that errors loading external subtitle files do not cause playback
to fail ([#8430](https://github.com/google/ExoPlayer/issues/8430)). A
so that errors loading external subtitle files do not cause playback to
fail ([#8430](https://github.com/google/ExoPlayer/issues/8430)). A
warning will be logged by `SingleSampleMediaPeriod` whenever a load
error is treated as though the end of the stream has been reached.
* Time out on release to prevent ANRs if an underlying platform call is
@ -921,9 +925,8 @@
([#7847](https://github.com/google/ExoPlayer/issues/7847)).
* Drop key and provision responses if `DefaultDrmSession` is released
while waiting for the response. This prevents harmless log messages of
the form:
`IllegalStateException: sending message to a Handler on a dead thread`
([#8328](https://github.com/google/ExoPlayer/issues/8328)).
the form: `IllegalStateException: sending message to a Handler on a dead
thread` ([#8328](https://github.com/google/ExoPlayer/issues/8328)).
* Allow apps to fully customize DRM behaviour for each `MediaItem` by
passing a `DrmSessionManagerProvider` to `MediaSourceFactory`
([#8466](https://github.com/google/ExoPlayer/issues/8466)).
@ -938,8 +941,8 @@
existing decoder instance for the new format, and if not then the
reasons why.
* Video:
* Fall back to AVC/HEVC decoders for Dolby Vision streams with level 10
to 13 ([#8530](https://github.com/google/ExoPlayer/issues/8530)).
* Fall back to AVC/HEVC decoders for Dolby Vision streams with level 10 to
13 ([#8530](https://github.com/google/ExoPlayer/issues/8530)).
* Fix VP9 format capability checks on API level 23 and earlier. The
platform does not correctly report the VP9 level supported by the
decoder in this case, so we estimate it based on the decoder's maximum
@ -1021,8 +1024,8 @@
* `ExtractorsMediaSource.Factory.setMinLoadableRetryCount(int)`. Use
`ExtractorsMediaSource.Factory.setLoadErrorHandlingPolicy(LoadErrorHandlingPolicy)`
instead.
* `FixedTrackSelection.Factory`. If you need to disable adaptive
selection in `DefaultTrackSelector`, enable the
* `FixedTrackSelection.Factory`. If you need to disable adaptive selection
in `DefaultTrackSelector`, enable the
`DefaultTrackSelector.Parameters.forceHighestSupportedBitrate` flag.
* `HlsMediaSource.Factory.setMinLoadableRetryCount(int)`. Use
`HlsMediaSource.Factory.setLoadErrorHandlingPolicy(LoadErrorHandlingPolicy)`
@ -1035,8 +1038,8 @@
`MappedTrackInfo.getUnmappedTrackGroups()` instead.
* `MappedTrackInfo.length`. Use `MappedTrackInfo.getRendererCount()`
instead.
* `Player.DefaultEventListener.onTimelineChanged(Timeline, Object)`.
Use `Player.EventListener.onTimelineChanged(Timeline, int)` instead.
* `Player.DefaultEventListener.onTimelineChanged(Timeline, Object)`. Use
`Player.EventListener.onTimelineChanged(Timeline, int)` instead.
* `Player.setAudioAttributes(AudioAttributes)`. Use
`Player.AudioComponent.setAudioAttributes(AudioAttributes, boolean)`
instead.
@ -1052,8 +1055,8 @@
`SimpleExoPlayer.removeVideoListener(VideoListener)` instead.
* `SimpleExoPlayer.getAudioStreamType()`. Use
`SimpleExoPlayer.getAudioAttributes()` instead.
* `SimpleExoPlayer.setAudioDebugListener(AudioRendererEventListener)`.
Use `SimpleExoPlayer.addAnalyticsListener(AnalyticsListener)` instead.
* `SimpleExoPlayer.setAudioDebugListener(AudioRendererEventListener)`. Use
`SimpleExoPlayer.addAnalyticsListener(AnalyticsListener)` instead.
* `SimpleExoPlayer.setAudioStreamType(int)`. Use
`SimpleExoPlayer.setAudioAttributes(AudioAttributes)` instead.
* `SimpleExoPlayer.setMetadataOutput(MetadataOutput)`. Use
@ -1064,12 +1067,11 @@
* `SimpleExoPlayer.setPlaybackParams(PlaybackParams)`. Use
`SimpleExoPlayer.setPlaybackParameters(PlaybackParameters)` instead.
* `SimpleExoPlayer.setTextOutput(TextOutput)`. Use
`SimpleExoPlayer.addTextOutput(TextOutput)` instead. If your
application is calling `SimpleExoPlayer.setTextOutput(null)`, make sure
to replace this call with a call to
`SimpleExoPlayer.removeTextOutput(TextOutput)`.
* `SimpleExoPlayer.setVideoDebugListener(VideoRendererEventListener)`.
Use `SimpleExoPlayer.addAnalyticsListener(AnalyticsListener)` instead.
`SimpleExoPlayer.addTextOutput(TextOutput)` instead. If your application
is calling `SimpleExoPlayer.setTextOutput(null)`, make sure to replace
this call with a call to `SimpleExoPlayer.removeTextOutput(TextOutput)`.
* `SimpleExoPlayer.setVideoDebugListener(VideoRendererEventListener)`. Use
`SimpleExoPlayer.addAnalyticsListener(AnalyticsListener)` instead.
* `SimpleExoPlayer.setVideoListener(VideoListener)`. Use
`SimpleExoPlayer.addVideoListener(VideoListener)` instead. If your
application is calling `SimpleExoPlayer.setVideoListener(null)`, make
@ -1093,7 +1095,7 @@
`SsMediaSource.Factory.setLoadErrorHandlingPolicy(LoadErrorHandlingPolicy)`
instead.
### 2.12.3 (2021-01-13) ###
### 2.12.3 (2021-01-13)
* Core library:
* Fix `MediaCodecRenderer` issue where empty streams would fail to play in
@ -1130,7 +1132,7 @@
fix a deadlock while creating PlaybackStateCompat internally.
([#8011](https://github.com/google/ExoPlayer/issues/8011)).
### 2.12.2 (2020-12-01) ###
### 2.12.2 (2020-12-01)
* Core library:
* Suppress exceptions from registering and unregistering the stream volume
@ -1191,7 +1193,7 @@
* Allow to remove all playlist items that makes the player reset
([#8047](https://github.com/google/ExoPlayer/issues/8047)).
### 2.12.1 (2020-10-23) ###
### 2.12.1 (2020-10-23)
* Core library:
* Fix issue where `Player.setMediaItems` would ignore its `resetPosition`
@ -1230,7 +1232,7 @@
([#8058](https://github.com/google/ExoPlayer/issues/8058)).
* Extractors:
* MP4:
* Add support for `_mp2` boxes
* Add support for `_mp2` boxes
([#7967](https://github.com/google/ExoPlayer/issues/7967)).
* Fix playback of files containing `pcm_alaw` or `pcm_mulaw` audio
tracks, by enabling sample rechunking for such tracks.
@ -1266,11 +1268,11 @@
([#7961](https://github.com/google/ExoPlayer/issues/7961)).
* Fix incorrect truncation of large cue point positions
([#8067](https://github.com/google/ExoPlayer/issues/8067)).
* Upgrade IMA SDK dependency to 3.20.1. This brings in a fix for
companion ads rendering when targeting API 29
* Upgrade IMA SDK dependency to 3.20.1. This brings in a fix for companion
ads rendering when targeting API 29
([#6432](https://github.com/google/ExoPlayer/issues/6432)).
### 2.12.0 (2020-09-11) ###
### 2.12.0 (2020-09-11)
To learn more about what's new in 2.12, read the corresponding
[blog post](https://medium.com/google-exoplayer/exoplayer-2-12-whats-new-e43ef8ff72e7).
@ -1301,8 +1303,7 @@ To learn more about what's new in 2.12, read the corresponding
* Remove `PlaybackParameters.skipSilence`, and replace it with
`AudioComponent.setSkipSilenceEnabled`. This method is also
available on `SimpleExoPlayer`. An
`AudioListener.onSkipSilenceEnabledChanged` callback is also
added.
`AudioListener.onSkipSilenceEnabledChanged` callback is also added.
* Add `TextComponent.getCurrentCues` to get the current cues. This
method is also available on `SimpleExoPlayer`. The current cues are
no longer automatically forwarded to a `TextOutput` when it's added
@ -1630,20 +1631,19 @@ To learn more about what's new in 2.12, read the corresponding
* Add support for downloading DRM-protected content using offline Widevine
licenses.
### 2.11.8 (2020-08-25) ###
### 2.11.8 (2020-08-25)
* Fix distorted playback of floating point audio when samples exceed the
`[-1, 1]` nominal range.
* Fix distorted playback of floating point audio when samples exceed the `[-1,
1]` nominal range.
* MP4:
* Add support for `piff` and `isml` brands
([#7584](https://github.com/google/ExoPlayer/issues/7584)).
* Fix playback of very short MP4 files.
* FMP4:
* Fix `saiz` and `senc` sample count checks, resolving a "length
mismatch" `ParserException` when playing certain protected FMP4 streams
* Fix `saiz` and `senc` sample count checks, resolving a "length mismatch"
`ParserException` when playing certain protected FMP4 streams
([#7592](https://github.com/google/ExoPlayer/issues/7592)).
* Fix handling of `traf` boxes containing multiple `sbgp` or `sgpd`
boxes.
* Fix handling of `traf` boxes containing multiple `sbgp` or `sgpd` boxes.
* FLV: Ignore `SCRIPTDATA` segments with invalid name types, rather than
failing playback ([#7675](https://github.com/google/ExoPlayer/issues/7675)).
* Better infer the content type of `.ism` and `.isml` streaming URLs.
@ -1656,12 +1656,12 @@ To learn more about what's new in 2.12, read the corresponding
* Demo app: Fix playback of ClearKey protected content on API level 26 and
earlier ([#7735](https://github.com/google/ExoPlayer/issues/7735)).
### 2.11.7 (2020-06-29) ###
### 2.11.7 (2020-06-29)
* IMA extension: Fix the way postroll "content complete" notifications are
handled to avoid repeatedly refreshing the timeline after playback ends.
### 2.11.6 (2020-06-19) ###
### 2.11.6 (2020-06-19)
* UI: Prevent `PlayerView` from temporarily hiding the video surface when
seeking to an unprepared period within the current window. For example when
@ -1676,14 +1676,14 @@ To learn more about what's new in 2.12, read the corresponding
([#7508](https://github.com/google/ExoPlayer/issues/7508)).
* Fix a bug where the number of ads in an ad group couldn't change
([#7477](https://github.com/google/ExoPlayer/issues/7477)).
* Work around unexpected `pauseAd`/`stopAd` for ads that have preloaded
on seeking to another position
* Work around unexpected `pauseAd`/`stopAd` for ads that have preloaded on
seeking to another position
([#7492](https://github.com/google/ExoPlayer/issues/7492)).
* Fix incorrect rounding of ad cue points.
* Fix handling of postrolls preloading
([#7518](https://github.com/google/ExoPlayer/issues/7518)).
### 2.11.5 (2020-06-05) ###
### 2.11.5 (2020-06-05)
* Improve the smoothness of video playback immediately after starting, seeking
or resuming a playback
@ -1691,8 +1691,8 @@ To learn more about what's new in 2.12, read the corresponding
* Add `SilenceMediaSource.Factory` to support tags.
* Enable the configuration of `SilenceSkippingAudioProcessor`
([#6705](https://github.com/google/ExoPlayer/issues/6705)).
* Fix bug where `PlayerMessages` throw an exception after `MediaSources`
are removed from the playlist
* Fix bug where `PlayerMessages` throw an exception after `MediaSources` are
removed from the playlist
([#7278](https://github.com/google/ExoPlayer/issues/7278)).
* Fix "Not allowed to start service" `IllegalStateException` in
`DownloadService`
@ -1724,13 +1724,11 @@ To learn more about what's new in 2.12, read the corresponding
([#7303](https://github.com/google/ExoPlayer/issues/7303)).
* Add `showScrubber` and `hideScrubber` methods to `DefaultTimeBar`.
* Text:
* Use anti-aliasing and bitmap filtering when displaying bitmap
subtitles.
* Use anti-aliasing and bitmap filtering when displaying bitmap subtitles.
* Fix `SubtitlePainter` to render `EDGE_TYPE_OUTLINE` using the correct
color.
* IMA extension:
* Upgrade to IMA SDK version 3.19.0, and migrate to new
preloading APIs
* Upgrade to IMA SDK version 3.19.0, and migrate to new preloading APIs
([#6429](https://github.com/google/ExoPlayer/issues/6429)). This fixes
several issues involving preloading and handling of ad loading error
cases: ([#4140](https://github.com/google/ExoPlayer/issues/4140),

View file

@ -80,6 +80,7 @@ public class TrackSelectionParameters implements Bundleable {
private int viewportHeight;
private boolean viewportOrientationMayChange;
private ImmutableList<String> preferredVideoMimeTypes;
private @C.RoleFlags int preferredVideoRoleFlags;
// Audio
private ImmutableList<String> preferredAudioLanguages;
private @C.RoleFlags int preferredAudioRoleFlags;
@ -111,6 +112,7 @@ public class TrackSelectionParameters implements Bundleable {
viewportHeight = Integer.MAX_VALUE;
viewportOrientationMayChange = true;
preferredVideoMimeTypes = ImmutableList.of();
preferredVideoRoleFlags = 0;
// Audio
preferredAudioLanguages = ImmutableList.of();
preferredAudioRoleFlags = 0;
@ -183,6 +185,10 @@ public class TrackSelectionParameters implements Bundleable {
firstNonNull(
bundle.getStringArray(keyForField(FIELD_PREFERRED_VIDEO_MIMETYPES)),
new String[0]));
preferredVideoRoleFlags =
bundle.getInt(
keyForField(FIELD_PREFERRED_VIDEO_ROLE_FLAGS),
DEFAULT_WITHOUT_CONTEXT.preferredVideoRoleFlags);
// Audio
String[] preferredAudioLanguages1 =
firstNonNull(
@ -261,6 +267,7 @@ public class TrackSelectionParameters implements Bundleable {
viewportHeight = parameters.viewportHeight;
viewportOrientationMayChange = parameters.viewportOrientationMayChange;
preferredVideoMimeTypes = parameters.preferredVideoMimeTypes;
preferredVideoRoleFlags = parameters.preferredVideoRoleFlags;
// Audio
preferredAudioLanguages = parameters.preferredAudioLanguages;
preferredAudioRoleFlags = parameters.preferredAudioRoleFlags;
@ -441,6 +448,17 @@ public class TrackSelectionParameters implements Bundleable {
return this;
}
/**
* Sets the preferred {@link C.RoleFlags} for video tracks.
*
* @param preferredVideoRoleFlags Preferred video role flags.
* @return This builder.
*/
public Builder setPreferredVideoRoleFlags(@C.RoleFlags int preferredVideoRoleFlags) {
this.preferredVideoRoleFlags = preferredVideoRoleFlags;
return this;
}
// Audio
/**
@ -770,6 +788,11 @@ public class TrackSelectionParameters implements Bundleable {
* no preference. The default is an empty list.
*/
public final ImmutableList<String> preferredVideoMimeTypes;
/**
* The preferred {@link C.RoleFlags} for video tracks. {@code 0} selects the default track if
* there is one, or the first track if there's no default. The default value is {@code 0}.
*/
public final @C.RoleFlags int preferredVideoRoleFlags;
// Audio
/**
* The preferred languages for audio and forced text tracks as IETF BCP 47 conformant tags in
@ -853,6 +876,7 @@ public class TrackSelectionParameters implements Bundleable {
this.viewportHeight = builder.viewportHeight;
this.viewportOrientationMayChange = builder.viewportOrientationMayChange;
this.preferredVideoMimeTypes = builder.preferredVideoMimeTypes;
this.preferredVideoRoleFlags = builder.preferredVideoRoleFlags;
// Audio
this.preferredAudioLanguages = builder.preferredAudioLanguages;
this.preferredAudioRoleFlags = builder.preferredAudioRoleFlags;
@ -898,6 +922,7 @@ public class TrackSelectionParameters implements Bundleable {
&& viewportWidth == other.viewportWidth
&& viewportHeight == other.viewportHeight
&& preferredVideoMimeTypes.equals(other.preferredVideoMimeTypes)
&& preferredVideoRoleFlags == other.preferredVideoRoleFlags
// Audio
&& preferredAudioLanguages.equals(other.preferredAudioLanguages)
&& preferredAudioRoleFlags == other.preferredAudioRoleFlags
@ -930,6 +955,7 @@ public class TrackSelectionParameters implements Bundleable {
result = 31 * result + viewportWidth;
result = 31 * result + viewportHeight;
result = 31 * result + preferredVideoMimeTypes.hashCode();
result = 31 * result + preferredVideoRoleFlags;
// Audio
result = 31 * result + preferredAudioLanguages.hashCode();
result = 31 * result + preferredAudioRoleFlags;
@ -978,6 +1004,7 @@ public class TrackSelectionParameters implements Bundleable {
FIELD_SELECTION_OVERRIDE_KEYS,
FIELD_SELECTION_OVERRIDE_VALUES,
FIELD_DISABLED_TRACK_TYPE,
FIELD_PREFERRED_VIDEO_ROLE_FLAGS
})
private @interface FieldNumber {}
@ -1006,6 +1033,7 @@ public class TrackSelectionParameters implements Bundleable {
private static final int FIELD_SELECTION_OVERRIDE_KEYS = 23;
private static final int FIELD_SELECTION_OVERRIDE_VALUES = 24;
private static final int FIELD_DISABLED_TRACK_TYPE = 25;
private static final int FIELD_PREFERRED_VIDEO_ROLE_FLAGS = 26;
@Override
public Bundle toBundle() {
@ -1027,6 +1055,7 @@ public class TrackSelectionParameters implements Bundleable {
bundle.putStringArray(
keyForField(FIELD_PREFERRED_VIDEO_MIMETYPES),
preferredVideoMimeTypes.toArray(new String[0]));
bundle.putInt(keyForField(FIELD_PREFERRED_VIDEO_ROLE_FLAGS), preferredVideoRoleFlags);
// Audio
bundle.putStringArray(
keyForField(FIELD_PREFERRED_AUDIO_LANGUAGES),

View file

@ -27,6 +27,7 @@ import androidx.annotation.Nullable;
import com.google.android.exoplayer2.Bundleable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.C.FormatSupport;
import com.google.android.exoplayer2.C.RoleFlags;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.Renderer;
@ -368,6 +369,13 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return this;
}
@Override
public DefaultTrackSelector.ParametersBuilder setPreferredVideoRoleFlags(
@RoleFlags int preferredVideoRoleFlags) {
super.setPreferredVideoRoleFlags(preferredVideoRoleFlags);
return this;
}
// Audio
@Override
@ -2468,6 +2476,14 @@ public class DefaultTrackSelector extends MappingTrackSelector {
}
}
private static int getRoleFlagMatchScore(int trackRoleFlags, int preferredRoleFlags) {
if (trackRoleFlags != 0 && trackRoleFlags == preferredRoleFlags) {
// Prefer perfect match over partial matches.
return Integer.MAX_VALUE;
}
return Integer.bitCount(trackRoleFlags & preferredRoleFlags);
}
/** Represents how well a video track matches the selection {@link Parameters}. */
protected static final class VideoTrackScore implements Comparable<VideoTrackScore> {
@ -2483,6 +2499,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
private final int bitrate;
private final int pixelCount;
private final int preferredMimeTypeMatchIndex;
private final int preferredRoleFlagsScore;
private final boolean hasMainOrNoRoleFlag;
public VideoTrackScore(
Format format,
@ -2510,6 +2528,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
isSupported(formatSupport, /* allowExceedsCapabilities= */ false);
bitrate = format.bitrate;
pixelCount = format.getPixelCount();
preferredRoleFlagsScore =
getRoleFlagMatchScore(format.roleFlags, parameters.preferredVideoRoleFlags);
hasMainOrNoRoleFlag = format.roleFlags == 0 || (format.roleFlags & C.ROLE_FLAG_MAIN) != 0;
int bestMimeTypeMatchIndex = Integer.MAX_VALUE;
for (int i = 0; i < parameters.preferredVideoMimeTypes.size(); i++) {
if (format.sampleMimeType != null
@ -2537,6 +2558,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
: FORMAT_VALUE_ORDERING.reverse();
return ComparisonChain.start()
.compareFalseFirst(this.isWithinRendererCapabilities, other.isWithinRendererCapabilities)
.compare(this.preferredRoleFlagsScore, other.preferredRoleFlagsScore)
.compareFalseFirst(this.hasMainOrNoRoleFlag, other.hasMainOrNoRoleFlag)
.compareFalseFirst(this.isWithinMaxConstraints, other.isWithinMaxConstraints)
.compareFalseFirst(this.isWithinMinConstraints, other.isWithinMinConstraints)
.compare(
@ -2568,6 +2591,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
private final int preferredLanguageScore;
private final int preferredLanguageIndex;
private final int preferredRoleFlagsScore;
private final boolean hasMainOrNoRoleFlag;
private final int localeLanguageMatchIndex;
private final int localeLanguageScore;
private final boolean isDefaultSelectionFlag;
@ -2598,7 +2622,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
preferredLanguageIndex = bestLanguageIndex;
preferredLanguageScore = bestLanguageScore;
preferredRoleFlagsScore =
Integer.bitCount(format.roleFlags & parameters.preferredAudioRoleFlags);
getRoleFlagMatchScore(format.roleFlags, parameters.preferredAudioRoleFlags);
hasMainOrNoRoleFlag = format.roleFlags == 0 || (format.roleFlags & C.ROLE_FLAG_MAIN) != 0;
isDefaultSelectionFlag = (format.selectionFlags & C.SELECTION_FLAG_DEFAULT) != 0;
channelCount = format.channelCount;
sampleRate = format.sampleRate;
@ -2656,6 +2681,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
Ordering.natural().reverse())
.compare(this.preferredLanguageScore, other.preferredLanguageScore)
.compare(this.preferredRoleFlagsScore, other.preferredRoleFlagsScore)
.compareFalseFirst(this.hasMainOrNoRoleFlag, other.hasMainOrNoRoleFlag)
.compareFalseFirst(this.isWithinConstraints, other.isWithinConstraints)
.compare(
this.preferredMimeTypeMatchIndex,
@ -2732,7 +2758,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
preferredLanguageIndex = bestLanguageIndex;
preferredLanguageScore = bestLanguageScore;
preferredRoleFlagsScore =
Integer.bitCount(format.roleFlags & parameters.preferredTextRoleFlags);
getRoleFlagMatchScore(format.roleFlags, parameters.preferredTextRoleFlags);
hasCaptionRoleFlags =
(format.roleFlags & (C.ROLE_FLAG_CAPTION | C.ROLE_FLAG_DESCRIBES_MUSIC_AND_SOUND)) != 0;
boolean selectedAudioLanguageUndetermined =

View file

@ -594,7 +594,7 @@ public final class DefaultTrackSelectorTest {
}
/**
* Tests that track selector will select audio track with the highest number of matching role
* Tests that track selector will select the audio track with the highest number of matching role
* flags given by {@link Parameters}.
*/
@Test
@ -619,6 +619,17 @@ public final class DefaultTrackSelectorTest {
periodId,
TIMELINE);
assertFixedSelection(result.selections[0], trackGroups, moreRoleFlags);
// Also verify that exact match between parameters and tracks is preferred.
trackSelector.setParameters(
defaultParameters.buildUpon().setPreferredAudioRoleFlags(C.ROLE_FLAG_CAPTION));
result =
trackSelector.selectTracks(
new RendererCapabilities[] {ALL_AUDIO_FORMAT_SUPPORTED_RENDERER_CAPABILITIES},
trackGroups,
periodId,
TIMELINE);
assertFixedSelection(result.selections[0], trackGroups, lessRoleFlags);
}
/**
@ -1279,6 +1290,45 @@ public final class DefaultTrackSelectorTest {
assertFixedSelection(result.selections[1], trackGroups, german);
}
/**
* Tests that track selector will select the text track with the highest number of matching role
* flags given by {@link Parameters}.
*/
@Test
public void selectTracks_withPreferredTextRoleFlags_selectPreferredTrack() throws Exception {
Format.Builder formatBuilder = TEXT_FORMAT.buildUpon();
Format noRoleFlags = formatBuilder.build();
Format lessRoleFlags = formatBuilder.setRoleFlags(C.ROLE_FLAG_CAPTION).build();
Format moreRoleFlags =
formatBuilder
.setRoleFlags(C.ROLE_FLAG_CAPTION | C.ROLE_FLAG_COMMENTARY | C.ROLE_FLAG_DUB)
.build();
TrackGroupArray trackGroups = wrapFormats(noRoleFlags, moreRoleFlags, lessRoleFlags);
trackSelector.setParameters(
defaultParameters
.buildUpon()
.setPreferredTextRoleFlags(C.ROLE_FLAG_CAPTION | C.ROLE_FLAG_COMMENTARY));
TrackSelectorResult result =
trackSelector.selectTracks(
new RendererCapabilities[] {ALL_TEXT_FORMAT_SUPPORTED_RENDERER_CAPABILITIES},
trackGroups,
periodId,
TIMELINE);
assertFixedSelection(result.selections[0], trackGroups, moreRoleFlags);
// Also verify that exact match between parameters and tracks is preferred.
trackSelector.setParameters(
defaultParameters.buildUpon().setPreferredTextRoleFlags(C.ROLE_FLAG_CAPTION));
result =
trackSelector.selectTracks(
new RendererCapabilities[] {ALL_TEXT_FORMAT_SUPPORTED_RENDERER_CAPABILITIES},
trackGroups,
periodId,
TIMELINE);
assertFixedSelection(result.selections[0], trackGroups, lessRoleFlags);
}
/**
* Tests that track selector will select the lowest bitrate supported audio track when {@link
* Parameters#forceLowestBitrate} is set.
@ -1809,6 +1859,39 @@ public final class DefaultTrackSelectorTest {
assertFixedSelection(result.selections[0], trackGroups, formatAv1);
}
/**
* Tests that track selector will select the video track with the highest number of matching role
* flags given by {@link Parameters}.
*/
@Test
public void selectTracks_withPreferredVideoRoleFlags_selectPreferredTrack() throws Exception {
Format.Builder formatBuilder = VIDEO_FORMAT.buildUpon();
Format noRoleFlags = formatBuilder.build();
Format lessRoleFlags = formatBuilder.setRoleFlags(C.ROLE_FLAG_CAPTION).build();
Format moreRoleFlags =
formatBuilder
.setRoleFlags(C.ROLE_FLAG_CAPTION | C.ROLE_FLAG_COMMENTARY | C.ROLE_FLAG_DUB)
.build();
TrackGroupArray trackGroups = wrapFormats(noRoleFlags, moreRoleFlags, lessRoleFlags);
trackSelector.setParameters(
defaultParameters
.buildUpon()
.setPreferredVideoRoleFlags(C.ROLE_FLAG_CAPTION | C.ROLE_FLAG_COMMENTARY));
TrackSelectorResult result =
trackSelector.selectTracks(
new RendererCapabilities[] {VIDEO_CAPABILITIES}, trackGroups, periodId, TIMELINE);
assertFixedSelection(result.selections[0], trackGroups, moreRoleFlags);
// Also verify that exact match between parameters and tracks is preferred.
trackSelector.setParameters(
defaultParameters.buildUpon().setPreferredVideoRoleFlags(C.ROLE_FLAG_CAPTION));
result =
trackSelector.selectTracks(
new RendererCapabilities[] {VIDEO_CAPABILITIES}, trackGroups, periodId, TIMELINE);
assertFixedSelection(result.selections[0], trackGroups, lessRoleFlags);
}
@Test
public void selectTracks_withPreferredAudioMimeTypes_selectsTrackWithPreferredMimeType()
throws Exception {