Commit cdcc7012 by tianyifeng Committed by Marc Baechinger

Reselect track when renderer capabilities change

* Implement RendererCapabilities.Listener in DefaultTrackSelector.
* Add new methods TrackSelector.invalidateForRendererCapabilitiesChange and TrackSelector.InvalidateListener.onRendererCapabilitiesChanged.
* Add new field allowInvalidateSelectionsOnRendererCapabilitiesChange to DefaultTrackSelector.Parameter to allow opt-in of the renderer capabilities detection feature.
* Add logics of triggering track reselection when renderer capabilities change.

PiperOrigin-RevId: 529067433
parent 44843304
...@@ -157,6 +157,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -157,6 +157,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
private static final int MSG_SET_PAUSE_AT_END_OF_WINDOW = 23; private static final int MSG_SET_PAUSE_AT_END_OF_WINDOW = 23;
private static final int MSG_SET_OFFLOAD_SCHEDULING_ENABLED = 24; private static final int MSG_SET_OFFLOAD_SCHEDULING_ENABLED = 24;
private static final int MSG_ATTEMPT_RENDERER_ERROR_RECOVERY = 25; private static final int MSG_ATTEMPT_RENDERER_ERROR_RECOVERY = 25;
private static final int MSG_RENDERER_CAPABILITIES_CHANGED = 26;
private static final int ACTIVE_INTERVAL_MS = 10; private static final int ACTIVE_INTERVAL_MS = 10;
private static final int IDLE_INTERVAL_MS = 1000; private static final int IDLE_INTERVAL_MS = 1000;
...@@ -473,6 +474,11 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -473,6 +474,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
handler.sendEmptyMessage(MSG_TRACK_SELECTION_INVALIDATED); handler.sendEmptyMessage(MSG_TRACK_SELECTION_INVALIDATED);
} }
@Override
public void onRendererCapabilitiesChanged(Renderer renderer) {
handler.sendEmptyMessage(MSG_RENDERER_CAPABILITIES_CHANGED);
}
// DefaultMediaClock.PlaybackParametersListener implementation. // DefaultMediaClock.PlaybackParametersListener implementation.
@Override @Override
...@@ -568,6 +574,9 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -568,6 +574,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
case MSG_ATTEMPT_RENDERER_ERROR_RECOVERY: case MSG_ATTEMPT_RENDERER_ERROR_RECOVERY:
attemptRendererErrorRecovery(); attemptRendererErrorRecovery();
break; break;
case MSG_RENDERER_CAPABILITIES_CHANGED:
reselectTracksInternalAndSeek();
break;
case MSG_RELEASE: case MSG_RELEASE:
releaseInternal(); releaseInternal();
// Return immediately to not send playback info updates after release. // Return immediately to not send playback info updates after release.
......
...@@ -439,6 +439,11 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media ...@@ -439,6 +439,11 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
DecoderReuseEvaluation evaluation = codecInfo.canReuseCodec(oldFormat, newFormat); DecoderReuseEvaluation evaluation = codecInfo.canReuseCodec(oldFormat, newFormat);
@DecoderDiscardReasons int discardReasons = evaluation.discardReasons; @DecoderDiscardReasons int discardReasons = evaluation.discardReasons;
if (isBypassPossible(newFormat)) {
// We prefer direct audio playback so that for multi-channel tracks the audio is not downmixed
// to stereo.
discardReasons |= DecoderReuseEvaluation.DISCARD_REASON_AUDIO_BYPASS_POSSIBLE;
}
if (getCodecMaxInputSize(codecInfo, newFormat) > codecMaxInputSize) { if (getCodecMaxInputSize(codecInfo, newFormat) > codecMaxInputSize) {
discardReasons |= DISCARD_REASON_MAX_INPUT_SIZE_EXCEEDED; discardReasons |= DISCARD_REASON_MAX_INPUT_SIZE_EXCEEDED;
} }
......
...@@ -78,7 +78,8 @@ public final class DecoderReuseEvaluation { ...@@ -78,7 +78,8 @@ public final class DecoderReuseEvaluation {
DISCARD_REASON_VIDEO_COLOR_INFO_CHANGED, DISCARD_REASON_VIDEO_COLOR_INFO_CHANGED,
DISCARD_REASON_AUDIO_CHANNEL_COUNT_CHANGED, DISCARD_REASON_AUDIO_CHANNEL_COUNT_CHANGED,
DISCARD_REASON_AUDIO_SAMPLE_RATE_CHANGED, DISCARD_REASON_AUDIO_SAMPLE_RATE_CHANGED,
DISCARD_REASON_AUDIO_ENCODING_CHANGED DISCARD_REASON_AUDIO_ENCODING_CHANGED,
DISCARD_REASON_AUDIO_BYPASS_POSSIBLE
}) })
public @interface DecoderDiscardReasons {} public @interface DecoderDiscardReasons {}
...@@ -112,6 +113,8 @@ public final class DecoderReuseEvaluation { ...@@ -112,6 +113,8 @@ public final class DecoderReuseEvaluation {
public static final int DISCARD_REASON_AUDIO_SAMPLE_RATE_CHANGED = 1 << 13; public static final int DISCARD_REASON_AUDIO_SAMPLE_RATE_CHANGED = 1 << 13;
/** The audio encoding is changing. */ /** The audio encoding is changing. */
public static final int DISCARD_REASON_AUDIO_ENCODING_CHANGED = 1 << 14; public static final int DISCARD_REASON_AUDIO_ENCODING_CHANGED = 1 << 14;
/** The audio bypass mode is possible. */
public static final int DISCARD_REASON_AUDIO_BYPASS_POSSIBLE = 1 << 15;
/** The name of the decoder. */ /** The name of the decoder. */
public final String decoderName; public final String decoderName;
......
...@@ -489,7 +489,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -489,7 +489,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
return; return;
} }
if (sourceDrmSession == null && shouldUseBypass(inputFormat)) { if (isBypassPossible(inputFormat)) {
initBypass(inputFormat); initBypass(inputFormat);
return; return;
} }
...@@ -547,6 +547,19 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -547,6 +547,19 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
/** /**
* Returns whether buffers in the input format can be processed without a codec. * Returns whether buffers in the input format can be processed without a codec.
* *
* <p>This method returns the possibility of bypass mode with checking both the renderer
* capabilities and DRM protection.
*
* @param format The input {@link Format}.
* @return Whether playback bypassing {@link MediaCodec} is possible.
*/
protected final boolean isBypassPossible(Format format) {
return sourceDrmSession == null && shouldUseBypass(inputFormat);
}
/**
* Returns whether buffers in the input format can be processed without a codec.
*
* <p>This method is only called if the content is not DRM protected, because if the content is * <p>This method is only called if the content is not DRM protected, because if the content is
* DRM protected use of bypass is never possible. * DRM protected use of bypass is never possible.
* *
......
...@@ -107,7 +107,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -107,7 +107,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
* .build()); * .build());
* }</pre> * }</pre>
*/ */
public class DefaultTrackSelector extends MappingTrackSelector { public class DefaultTrackSelector extends MappingTrackSelector
implements RendererCapabilities.Listener {
private static final String TAG = "DefaultTrackSelector"; private static final String TAG = "DefaultTrackSelector";
private static final String AUDIO_CHANNEL_COUNT_CONSTRAINTS_WARN_MESSAGE = private static final String AUDIO_CHANNEL_COUNT_CONSTRAINTS_WARN_MESSAGE =
...@@ -754,6 +755,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -754,6 +755,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
private boolean exceedRendererCapabilitiesIfNecessary; private boolean exceedRendererCapabilitiesIfNecessary;
private boolean tunnelingEnabled; private boolean tunnelingEnabled;
private boolean allowMultipleAdaptiveSelections; private boolean allowMultipleAdaptiveSelections;
private boolean allowInvalidateSelectionsOnRendererCapabilitiesChange;
// Overrides // Overrides
private final SparseArray<Map<TrackGroupArray, @NullableType SelectionOverride>> private final SparseArray<Map<TrackGroupArray, @NullableType SelectionOverride>>
selectionOverrides; selectionOverrides;
...@@ -810,6 +812,8 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -810,6 +812,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
exceedRendererCapabilitiesIfNecessary = initialValues.exceedRendererCapabilitiesIfNecessary; exceedRendererCapabilitiesIfNecessary = initialValues.exceedRendererCapabilitiesIfNecessary;
tunnelingEnabled = initialValues.tunnelingEnabled; tunnelingEnabled = initialValues.tunnelingEnabled;
allowMultipleAdaptiveSelections = initialValues.allowMultipleAdaptiveSelections; allowMultipleAdaptiveSelections = initialValues.allowMultipleAdaptiveSelections;
allowInvalidateSelectionsOnRendererCapabilitiesChange =
initialValues.allowInvalidateSelectionsOnRendererCapabilitiesChange;
// Overrides // Overrides
selectionOverrides = cloneSelectionOverrides(initialValues.selectionOverrides); selectionOverrides = cloneSelectionOverrides(initialValues.selectionOverrides);
rendererDisabledFlags = initialValues.rendererDisabledFlags.clone(); rendererDisabledFlags = initialValues.rendererDisabledFlags.clone();
...@@ -873,6 +877,10 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -873,6 +877,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
bundle.getBoolean( bundle.getBoolean(
Parameters.FIELD_ALLOW_MULTIPLE_ADAPTIVE_SELECTIONS, Parameters.FIELD_ALLOW_MULTIPLE_ADAPTIVE_SELECTIONS,
defaultValue.allowMultipleAdaptiveSelections)); defaultValue.allowMultipleAdaptiveSelections));
setAllowInvalidateSelectionsOnRendererCapabilitiesChange(
bundle.getBoolean(
Parameters.FIELD_ALLOW_INVALIDATE_SELECTIONS_ON_RENDERER_CAPABILITIES_CHANGE,
defaultValue.allowInvalidateSelectionsOnRendererCapabilitiesChange));
// Overrides // Overrides
selectionOverrides = new SparseArray<>(); selectionOverrides = new SparseArray<>();
setSelectionOverridesFromBundle(bundle); setSelectionOverridesFromBundle(bundle);
...@@ -1286,6 +1294,21 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1286,6 +1294,21 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return this; return this;
} }
/**
* Sets whether to allow to invalidate selections on renderer capabilities change.
*
* @param allowInvalidateSelectionsOnRendererCapabilitiesChange Whether to allow to invalidate
* selections.
* @return This builder.
*/
@CanIgnoreReturnValue
public Builder setAllowInvalidateSelectionsOnRendererCapabilitiesChange(
boolean allowInvalidateSelectionsOnRendererCapabilitiesChange) {
this.allowInvalidateSelectionsOnRendererCapabilitiesChange =
allowInvalidateSelectionsOnRendererCapabilitiesChange;
return this;
}
@CanIgnoreReturnValue @CanIgnoreReturnValue
@Override @Override
public Builder addOverride(TrackSelectionOverride override) { public Builder addOverride(TrackSelectionOverride override) {
...@@ -1543,6 +1566,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1543,6 +1566,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
exceedRendererCapabilitiesIfNecessary = true; exceedRendererCapabilitiesIfNecessary = true;
tunnelingEnabled = false; tunnelingEnabled = false;
allowMultipleAdaptiveSelections = true; allowMultipleAdaptiveSelections = true;
allowInvalidateSelectionsOnRendererCapabilitiesChange = false;
} }
private static SparseArray<Map<TrackGroupArray, @NullableType SelectionOverride>> private static SparseArray<Map<TrackGroupArray, @NullableType SelectionOverride>>
...@@ -1715,6 +1739,12 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1715,6 +1739,12 @@ public class DefaultTrackSelector extends MappingTrackSelector {
*/ */
public final boolean allowMultipleAdaptiveSelections; public final boolean allowMultipleAdaptiveSelections;
/**
* Whether to allow to invalidate selections on renderer capabilities change. The default value
* is {@code false}.
*/
public final boolean allowInvalidateSelectionsOnRendererCapabilitiesChange;
// Overrides // Overrides
private final SparseArray<Map<TrackGroupArray, @NullableType SelectionOverride>> private final SparseArray<Map<TrackGroupArray, @NullableType SelectionOverride>>
selectionOverrides; selectionOverrides;
...@@ -1739,6 +1769,8 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1739,6 +1769,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
exceedRendererCapabilitiesIfNecessary = builder.exceedRendererCapabilitiesIfNecessary; exceedRendererCapabilitiesIfNecessary = builder.exceedRendererCapabilitiesIfNecessary;
tunnelingEnabled = builder.tunnelingEnabled; tunnelingEnabled = builder.tunnelingEnabled;
allowMultipleAdaptiveSelections = builder.allowMultipleAdaptiveSelections; allowMultipleAdaptiveSelections = builder.allowMultipleAdaptiveSelections;
allowInvalidateSelectionsOnRendererCapabilitiesChange =
builder.allowInvalidateSelectionsOnRendererCapabilitiesChange;
// Overrides // Overrides
selectionOverrides = builder.selectionOverrides; selectionOverrides = builder.selectionOverrides;
rendererDisabledFlags = builder.rendererDisabledFlags; rendererDisabledFlags = builder.rendererDisabledFlags;
...@@ -1829,6 +1861,8 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1829,6 +1861,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
&& exceedRendererCapabilitiesIfNecessary == other.exceedRendererCapabilitiesIfNecessary && exceedRendererCapabilitiesIfNecessary == other.exceedRendererCapabilitiesIfNecessary
&& tunnelingEnabled == other.tunnelingEnabled && tunnelingEnabled == other.tunnelingEnabled
&& allowMultipleAdaptiveSelections == other.allowMultipleAdaptiveSelections && allowMultipleAdaptiveSelections == other.allowMultipleAdaptiveSelections
&& allowInvalidateSelectionsOnRendererCapabilitiesChange
== other.allowInvalidateSelectionsOnRendererCapabilitiesChange
// Overrides // Overrides
&& areRendererDisabledFlagsEqual(rendererDisabledFlags, other.rendererDisabledFlags) && areRendererDisabledFlagsEqual(rendererDisabledFlags, other.rendererDisabledFlags)
&& areSelectionOverridesEqual(selectionOverrides, other.selectionOverrides); && areSelectionOverridesEqual(selectionOverrides, other.selectionOverrides);
...@@ -1854,6 +1888,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1854,6 +1888,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
result = 31 * result + (exceedRendererCapabilitiesIfNecessary ? 1 : 0); result = 31 * result + (exceedRendererCapabilitiesIfNecessary ? 1 : 0);
result = 31 * result + (tunnelingEnabled ? 1 : 0); result = 31 * result + (tunnelingEnabled ? 1 : 0);
result = 31 * result + (allowMultipleAdaptiveSelections ? 1 : 0); result = 31 * result + (allowMultipleAdaptiveSelections ? 1 : 0);
result = 31 * result + (allowInvalidateSelectionsOnRendererCapabilitiesChange ? 1 : 0);
// Overrides (omitted from hashCode). // Overrides (omitted from hashCode).
return result; return result;
} }
...@@ -1894,6 +1929,8 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1894,6 +1929,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
Util.intToStringMaxRadix(FIELD_CUSTOM_ID_BASE + 15); Util.intToStringMaxRadix(FIELD_CUSTOM_ID_BASE + 15);
private static final String FIELD_CONSTRAIN_AUDIO_CHANNEL_COUNT_TO_DEVICE_CAPABILITIES = private static final String FIELD_CONSTRAIN_AUDIO_CHANNEL_COUNT_TO_DEVICE_CAPABILITIES =
Util.intToStringMaxRadix(FIELD_CUSTOM_ID_BASE + 16); Util.intToStringMaxRadix(FIELD_CUSTOM_ID_BASE + 16);
private static final String FIELD_ALLOW_INVALIDATE_SELECTIONS_ON_RENDERER_CAPABILITIES_CHANGE =
Util.intToStringMaxRadix(FIELD_CUSTOM_ID_BASE + 17);
@Override @Override
public Bundle toBundle() { public Bundle toBundle() {
...@@ -1930,6 +1967,9 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1930,6 +1967,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
FIELD_EXCEED_RENDERER_CAPABILITIES_IF_NECESSARY, exceedRendererCapabilitiesIfNecessary); FIELD_EXCEED_RENDERER_CAPABILITIES_IF_NECESSARY, exceedRendererCapabilitiesIfNecessary);
bundle.putBoolean(FIELD_TUNNELING_ENABLED, tunnelingEnabled); bundle.putBoolean(FIELD_TUNNELING_ENABLED, tunnelingEnabled);
bundle.putBoolean(FIELD_ALLOW_MULTIPLE_ADAPTIVE_SELECTIONS, allowMultipleAdaptiveSelections); bundle.putBoolean(FIELD_ALLOW_MULTIPLE_ADAPTIVE_SELECTIONS, allowMultipleAdaptiveSelections);
bundle.putBoolean(
FIELD_ALLOW_INVALIDATE_SELECTIONS_ON_RENDERER_CAPABILITIES_CHANGE,
allowInvalidateSelectionsOnRendererCapabilitiesChange);
putSelectionOverridesToBundle(bundle, selectionOverrides); putSelectionOverridesToBundle(bundle, selectionOverrides);
// Only true values are put into rendererDisabledFlags. // Only true values are put into rendererDisabledFlags.
...@@ -2353,6 +2393,19 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2353,6 +2393,19 @@ public class DefaultTrackSelector extends MappingTrackSelector {
} }
} }
@Override
@Nullable
public RendererCapabilities.Listener getRendererCapabilitiesListener() {
return this;
}
// RendererCapabilities.Listener implementation.
@Override
public void onRendererCapabilitiesChanged(Renderer renderer) {
maybeInvalidateForRendererCapabilitiesChange(renderer);
}
// MappingTrackSelector implementation. // MappingTrackSelector implementation.
@Override @Override
...@@ -2765,6 +2818,16 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2765,6 +2818,16 @@ public class DefaultTrackSelector extends MappingTrackSelector {
} }
} }
private void maybeInvalidateForRendererCapabilitiesChange(Renderer renderer) {
boolean shouldInvalidate;
synchronized (lock) {
shouldInvalidate = parameters.allowInvalidateSelectionsOnRendererCapabilitiesChange;
}
if (shouldInvalidate) {
invalidateForRendererCapabilitiesChange(renderer);
}
}
// Utility methods. // Utility methods.
private static void applyTrackSelectionOverrides( private static void applyTrackSelectionOverrides(
......
...@@ -99,6 +99,15 @@ public abstract class TrackSelector { ...@@ -99,6 +99,15 @@ public abstract class TrackSelector {
* longer valid. May be called from any thread. * longer valid. May be called from any thread.
*/ */
void onTrackSelectionsInvalidated(); void onTrackSelectionsInvalidated();
/**
* Called by a {@link TrackSelector} to indicate that selections it has previously made may no
* longer be valid due to the renderer capabilities change. This method is called from playback
* thread.
*
* @param renderer The renderer whose capabilities changed.
*/
default void onRendererCapabilitiesChanged(Renderer renderer) {}
} }
@Nullable private InvalidationListener listener; @Nullable private InvalidationListener listener;
...@@ -205,6 +214,18 @@ public abstract class TrackSelector { ...@@ -205,6 +214,18 @@ public abstract class TrackSelector {
} }
/** /**
* Calls {@link InvalidationListener#onRendererCapabilitiesChanged(Renderer)} to invalidate all
* previously generated track selections because a renderer's capabilities have changed.
*
* @param renderer The renderer whose capabilities changed.
*/
protected final void invalidateForRendererCapabilitiesChange(Renderer renderer) {
if (listener != null) {
listener.onRendererCapabilitiesChanged(renderer);
}
}
/**
* Returns a bandwidth meter which can be used by track selections to select tracks. Must only be * Returns a bandwidth meter which can be used by track selections to select tracks. Must only be
* called when the track selector is {@linkplain #init(InvalidationListener, BandwidthMeter) * called when the track selector is {@linkplain #init(InvalidationListener, BandwidthMeter)
* initialized}. * initialized}.
......
...@@ -28,6 +28,7 @@ import static com.google.android.exoplayer2.RendererCapabilities.HARDWARE_ACCELE ...@@ -28,6 +28,7 @@ import static com.google.android.exoplayer2.RendererCapabilities.HARDWARE_ACCELE
import static com.google.android.exoplayer2.RendererCapabilities.TUNNELING_NOT_SUPPORTED; import static com.google.android.exoplayer2.RendererCapabilities.TUNNELING_NOT_SUPPORTED;
import static com.google.android.exoplayer2.RendererConfiguration.DEFAULT; import static com.google.android.exoplayer2.RendererConfiguration.DEFAULT;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
...@@ -41,20 +42,24 @@ import com.google.android.exoplayer2.Bundleable; ...@@ -41,20 +42,24 @@ import com.google.android.exoplayer2.Bundleable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.RendererCapabilities; import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.RendererCapabilities.Capabilities; import com.google.android.exoplayer2.RendererCapabilities.Capabilities;
import com.google.android.exoplayer2.RendererConfiguration; import com.google.android.exoplayer2.RendererConfiguration;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.Tracks; import com.google.android.exoplayer2.Tracks;
import com.google.android.exoplayer2.audio.AudioRendererEventListener;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.testutil.FakeAudioRenderer;
import com.google.android.exoplayer2.testutil.FakeTimeline; import com.google.android.exoplayer2.testutil.FakeTimeline;
import com.google.android.exoplayer2.testutil.TestUtil; import com.google.android.exoplayer2.testutil.TestUtil;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.Parameters; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.Parameters;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.SelectionOverride; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.SelectionOverride;
import com.google.android.exoplayer2.trackselection.TrackSelector.InvalidationListener; import com.google.android.exoplayer2.trackselection.TrackSelector.InvalidationListener;
import com.google.android.exoplayer2.upstream.BandwidthMeter; import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.util.HandlerWrapper;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
...@@ -2452,6 +2457,36 @@ public final class DefaultTrackSelectorTest { ...@@ -2452,6 +2457,36 @@ public final class DefaultTrackSelectorTest {
} }
} }
@Test
public void onRendererCapabilitiesChangedWithDefaultParameters_notNotifyInvalidateListener() {
Renderer renderer =
new FakeAudioRenderer(
/* handler= */ mock(HandlerWrapper.class),
/* eventListener= */ mock(AudioRendererEventListener.class));
trackSelector.onRendererCapabilitiesChanged(renderer);
verify(invalidationListener, never()).onRendererCapabilitiesChanged(renderer);
}
@Test
public void
onRendererCapabilitiesChangedWithInvalidateSelectionsForRendererCapabilitiesChangeEnabled_notifyInvalidateListener() {
trackSelector.setParameters(
defaultParameters
.buildUpon()
.setAllowInvalidateSelectionsOnRendererCapabilitiesChange(true)
.build());
Renderer renderer =
new FakeAudioRenderer(
/* handler= */ mock(HandlerWrapper.class),
/* eventListener= */ mock(AudioRendererEventListener.class));
trackSelector.onRendererCapabilitiesChanged(renderer);
verify(invalidationListener).onRendererCapabilitiesChanged(renderer);
}
private static void assertSelections(TrackSelectorResult result, TrackSelection[] expected) { private static void assertSelections(TrackSelectorResult result, TrackSelection[] expected) {
assertThat(result.length).isEqualTo(expected.length); assertThat(result.length).isEqualTo(expected.length);
for (int i = 0; i < expected.length; i++) { for (int i = 0; i < expected.length; i++) {
...@@ -2572,6 +2607,7 @@ public final class DefaultTrackSelectorTest { ...@@ -2572,6 +2607,7 @@ public final class DefaultTrackSelectorTest {
.setExceedRendererCapabilitiesIfNecessary(false) .setExceedRendererCapabilitiesIfNecessary(false)
.setTunnelingEnabled(true) .setTunnelingEnabled(true)
.setAllowMultipleAdaptiveSelections(true) .setAllowMultipleAdaptiveSelections(true)
.setAllowInvalidateSelectionsOnRendererCapabilitiesChange(false)
.setSelectionOverride( .setSelectionOverride(
/* rendererIndex= */ 2, /* rendererIndex= */ 2,
new TrackGroupArray(VIDEO_TRACK_GROUP), new TrackGroupArray(VIDEO_TRACK_GROUP),
......
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