Skip to content

Commit

Permalink
Fix audio and text track selection in the multi-renderer case
Browse files Browse the repository at this point in the history
If we can select a track that has a strictly higher score than a
selection already made for a renderer of the same type, we should
prefer it.

Issue: #4711

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=212835895
  • Loading branch information
ojw28 committed Sep 13, 2018
1 parent 3e4115f commit 6f6f381
Show file tree
Hide file tree
Showing 3 changed files with 195 additions and 103 deletions.
3 changes: 3 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@
* Fix bugs reporting events for multi-period media sources
([#4492](https://github.com/google/ExoPlayer/issues/4492) and
[#4634](https://github.com/google/ExoPlayer/issues/4634)).
* Fix issue where the preferred audio or text track would not be selected if
mapped onto a secondary renderer of the corresponding type
([#4711](http://github.com/google/ExoPlayer/issues/4711)).
* Fix issue where errors of upcoming playlist items are thrown too early
([#4661](https://github.com/google/ExoPlayer/issues/4661)).
* Allow edit lists which do not start with a sync sample.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1318,32 +1318,49 @@ public void setTunnelingAudioSessionId(int tunnelingAudioSessionId) {
}
}

boolean selectedAudioTracks = false;
boolean selectedTextTracks = false;
AudioTrackScore selectedAudioTrackScore = null;
int selectedAudioRendererIndex = C.INDEX_UNSET;
int selectedTextTrackScore = Integer.MIN_VALUE;
int selectedTextRendererIndex = C.INDEX_UNSET;
for (int i = 0; i < rendererCount; i++) {
int trackType = mappedTrackInfo.getRendererType(i);
switch (trackType) {
case C.TRACK_TYPE_VIDEO:
// Already done. Do nothing.
break;
case C.TRACK_TYPE_AUDIO:
if (!selectedAudioTracks) {
rendererTrackSelections[i] =
selectAudioTrack(
mappedTrackInfo.getTrackGroups(i),
rendererFormatSupports[i],
rendererMixedMimeTypeAdaptationSupports[i],
params,
seenVideoRendererWithMappedTracks ? null : adaptiveTrackSelectionFactory);
selectedAudioTracks = rendererTrackSelections[i] != null;
Pair<TrackSelection, AudioTrackScore> audioSelection =
selectAudioTrack(
mappedTrackInfo.getTrackGroups(i),
rendererFormatSupports[i],
rendererMixedMimeTypeAdaptationSupports[i],
params,
seenVideoRendererWithMappedTracks ? null : adaptiveTrackSelectionFactory);
if (audioSelection != null
&& (selectedAudioTrackScore == null
|| audioSelection.second.compareTo(selectedAudioTrackScore) > 0)) {
if (selectedAudioRendererIndex != C.INDEX_UNSET) {
// We've already made a selection for another audio renderer, but it had a lower
// score. Clear the selection for that renderer.
rendererTrackSelections[selectedAudioRendererIndex] = null;
}
rendererTrackSelections[i] = audioSelection.first;
selectedAudioTrackScore = audioSelection.second;
selectedAudioRendererIndex = i;
}
break;
case C.TRACK_TYPE_TEXT:
if (!selectedTextTracks) {
rendererTrackSelections[i] =
selectTextTrack(
mappedTrackInfo.getTrackGroups(i), rendererFormatSupports[i], params);
selectedTextTracks = rendererTrackSelections[i] != null;
Pair<TrackSelection, Integer> textSelection =
selectTextTrack(mappedTrackInfo.getTrackGroups(i), rendererFormatSupports[i], params);
if (textSelection != null && textSelection.second > selectedTextTrackScore) {
if (selectedTextRendererIndex != C.INDEX_UNSET) {
// We've already made a selection for another text renderer, but it had a lower score.
// Clear the selection for that renderer.
rendererTrackSelections[selectedTextRendererIndex] = null;
}
rendererTrackSelections[i] = textSelection.first;
selectedTextTrackScore = textSelection.second;
selectedTextRendererIndex = i;
}
break;
default:
Expand Down Expand Up @@ -1599,10 +1616,11 @@ private static boolean isSupportedAdaptiveVideoTrack(
* @param params The selector's current constraint parameters.
* @param adaptiveTrackSelectionFactory A factory for generating adaptive track selections, or
* null if a fixed track selection is required.
* @return The {@link TrackSelection} for the renderer, or null if no selection was made.
* @return The {@link TrackSelection} and corresponding {@link AudioTrackScore}, or null if no
* selection was made.
* @throws ExoPlaybackException If an error occurs while selecting the tracks.
*/
protected @Nullable TrackSelection selectAudioTrack(
protected @Nullable Pair<TrackSelection, AudioTrackScore> selectAudioTrack(
TrackGroupArray groups,
int[][] formatSupports,
int mixedMimeTypeAdaptationSupports,
Expand Down Expand Up @@ -1635,6 +1653,8 @@ private static boolean isSupportedAdaptiveVideoTrack(
}

TrackGroup selectedGroup = groups.get(selectedGroupIndex);

TrackSelection selection = null;
if (!params.forceHighestSupportedBitrate
&& !params.forceLowestBitrate
&& adaptiveTrackSelectionFactory != null) {
Expand All @@ -1643,11 +1663,17 @@ private static boolean isSupportedAdaptiveVideoTrack(
getAdaptiveAudioTracks(
selectedGroup, formatSupports[selectedGroupIndex], params.allowMixedMimeAdaptiveness);
if (adaptiveTracks.length > 0) {
return adaptiveTrackSelectionFactory
.createTrackSelection(selectedGroup, getBandwidthMeter(), adaptiveTracks);
selection =
adaptiveTrackSelectionFactory.createTrackSelection(
selectedGroup, getBandwidthMeter(), adaptiveTracks);
}
}
return new FixedTrackSelection(selectedGroup, selectedTrackIndex);
if (selection == null) {
// We didn't make an adaptive selection, so make a fixed one instead.
selection = new FixedTrackSelection(selectedGroup, selectedTrackIndex);
}

return Pair.create(selection, Assertions.checkNotNull(selectedTrackScore));
}

private static int[] getAdaptiveAudioTracks(TrackGroup group, int[] formatSupport,
Expand Down Expand Up @@ -1712,10 +1738,11 @@ private static boolean isSupportedAdaptiveAudioTrack(Format format, int formatSu
* @param formatSupport The result of {@link RendererCapabilities#supportsFormat} for each mapped
* track, indexed by track group index and track index (in that order).
* @param params The selector's current constraint parameters.
* @return The {@link TrackSelection} for the renderer, or null if no selection was made.
* @return The {@link TrackSelection} and corresponding track score, or null if no selection was
* made.
* @throws ExoPlaybackException If an error occurs while selecting the tracks.
*/
protected @Nullable TrackSelection selectTextTrack(
protected @Nullable Pair<TrackSelection, Integer> selectTextTrack(
TrackGroupArray groups, int[][] formatSupport, Parameters params)
throws ExoPlaybackException {
TrackGroup selectedGroup = null;
Expand Down Expand Up @@ -1770,8 +1797,10 @@ private static boolean isSupportedAdaptiveAudioTrack(Format format, int formatSu
}
}
}
return selectedGroup == null ? null
: new FixedTrackSelection(selectedGroup, selectedTrackIndex);
return selectedGroup == null
? null
: Pair.create(
new FixedTrackSelection(selectedGroup, selectedTrackIndex), selectedTrackScore);
}

// General track selection methods.
Expand Down Expand Up @@ -2032,12 +2061,9 @@ private static Point getMaxVideoSizeInViewport(boolean orientationMayChange, int
}
}

/**
* A representation of how well a track fits with our track selection {@link Parameters}.
*
* <p>This is used to rank different audio tracks relatively with each other.
*/
/** Represents how well an audio track matches the selection {@link Parameters}. */
private static final class AudioTrackScore implements Comparable<AudioTrackScore> {

private final Parameters parameters;
private final int withinRendererCapabilitiesScore;
private final int matchLanguageScore;
Expand All @@ -2057,7 +2083,7 @@ public AudioTrackScore(Format format, Parameters parameters, int formatSupport)
}

/**
* Compares the score of the current track format with another {@link AudioTrackScore}.
* Compares this score with another.
*
* @param other The other score to compare to.
* @return A positive integer if this score is better than the other. Zero if they are equal. A
Expand Down Expand Up @@ -2086,35 +2112,6 @@ public int compareTo(@NonNull AudioTrackScore other) {
return resultSign * compareInts(this.bitrate, other.bitrate);
}
}

@Override
public boolean equals(@Nullable Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}

AudioTrackScore that = (AudioTrackScore) o;

return withinRendererCapabilitiesScore == that.withinRendererCapabilitiesScore
&& matchLanguageScore == that.matchLanguageScore
&& defaultSelectionFlagScore == that.defaultSelectionFlagScore
&& channelCount == that.channelCount && sampleRate == that.sampleRate
&& bitrate == that.bitrate;
}

@Override
public int hashCode() {
int result = withinRendererCapabilitiesScore;
result = 31 * result + matchLanguageScore;
result = 31 * result + defaultSelectionFlagScore;
result = 31 * result + channelCount;
result = 31 * result + sampleRate;
result = 31 * result + bitrate;
return result;
}
}

/**
Expand Down
Loading

0 comments on commit 6f6f381

Please sign in to comment.