diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 4ffd8c4e5d..06cfde8d6c 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -55,6 +55,9 @@
* Fix issue when calling `performClick` on `PlayerView` without
`PlayerControlView`
([#6260](https://github.com/google/ExoPlayer/issues/6260)).
+* Fix issue where playback speeds are not used in adaptive track selections
+ after manual selection changes for other renderers
+ ([#6256](https://github.com/google/ExoPlayer/issues/6256)).
### 2.10.3 ###
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/MediaPeriod.java b/library/core/src/main/java/com/google/android/exoplayer2/source/MediaPeriod.java
index f076eae32c..847c87b077 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/source/MediaPeriod.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/source/MediaPeriod.java
@@ -106,13 +106,16 @@ public interface MediaPeriod extends SequenceableLoader {
* Performs a track selection.
*
*
The call receives track {@code selections} for each renderer, {@code mayRetainStreamFlags}
- * indicating whether the existing {@code SampleStream} can be retained for each selection, and
+ * indicating whether the existing {@link SampleStream} can be retained for each selection, and
* the existing {@code stream}s themselves. The call will update {@code streams} to reflect the
* provided selections, clearing, setting and replacing entries as required. If an existing sample
* stream is retained but with the requirement that the consuming renderer be reset, then the
* corresponding flag in {@code streamResetFlags} will be set to true. This flag will also be set
* if a new sample stream is created.
*
+ *
Note that previously received {@link TrackSelection TrackSelections} are no longer valid and
+ * references need to be replaced even if the corresponding {@link SampleStream} is kept.
+ *
*
This method is only called after the period has been prepared.
*
* @param selections The renderer track selections.
diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashChunkSource.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashChunkSource.java
index 40d4e468bd..f7edf62182 100644
--- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashChunkSource.java
+++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashChunkSource.java
@@ -69,4 +69,11 @@ public interface DashChunkSource extends ChunkSource {
* @param newManifest The new manifest.
*/
void updateManifest(DashManifest newManifest, int periodIndex);
+
+ /**
+ * Updates the track selection.
+ *
+ * @param trackSelection The new track selection instance. Must be equivalent to the previous one.
+ */
+ void updateTrackSelection(TrackSelection trackSelection);
}
diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaPeriod.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaPeriod.java
index b34b677d45..5daa1a8fd5 100644
--- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaPeriod.java
+++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaPeriod.java
@@ -406,17 +406,27 @@ import java.util.regex.Pattern;
int[] streamIndexToTrackGroupIndex) {
// Create newly selected primary and event streams.
for (int i = 0; i < selections.length; i++) {
- if (streams[i] == null && selections[i] != null) {
+ TrackSelection selection = selections[i];
+ if (selection == null) {
+ continue;
+ }
+ if (streams[i] == null) {
+ // Create new stream for selection.
streamResetFlags[i] = true;
int trackGroupIndex = streamIndexToTrackGroupIndex[i];
TrackGroupInfo trackGroupInfo = trackGroupInfos[trackGroupIndex];
if (trackGroupInfo.trackGroupCategory == TrackGroupInfo.CATEGORY_PRIMARY) {
- streams[i] = buildSampleStream(trackGroupInfo, selections[i], positionUs);
+ streams[i] = buildSampleStream(trackGroupInfo, selection, positionUs);
} else if (trackGroupInfo.trackGroupCategory == TrackGroupInfo.CATEGORY_MANIFEST_EVENTS) {
EventStream eventStream = eventStreams.get(trackGroupInfo.eventStreamGroupIndex);
- Format format = selections[i].getTrackGroup().getFormat(0);
+ Format format = selection.getTrackGroup().getFormat(0);
streams[i] = new EventSampleStream(eventStream, format, manifest.dynamic);
}
+ } else if (streams[i] instanceof ChunkSampleStream) {
+ // Update selection in existing stream.
+ @SuppressWarnings("unchecked")
+ ChunkSampleStream stream = (ChunkSampleStream) streams[i];
+ stream.getChunkSource().updateTrackSelection(selection);
}
}
// Create newly selected embedded streams from the corresponding primary stream. Note that this
diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DefaultDashChunkSource.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DefaultDashChunkSource.java
index 2de81a2535..bcf0a1766a 100644
--- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DefaultDashChunkSource.java
+++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DefaultDashChunkSource.java
@@ -111,7 +111,6 @@ public class DefaultDashChunkSource implements DashChunkSource {
private final LoaderErrorThrower manifestLoaderErrorThrower;
private final int[] adaptationSetIndices;
- private final TrackSelection trackSelection;
private final int trackType;
private final DataSource dataSource;
private final long elapsedRealtimeOffsetMs;
@@ -120,6 +119,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
protected final RepresentationHolder[] representationHolders;
+ private TrackSelection trackSelection;
private DashManifest manifest;
private int periodIndex;
private IOException fatalError;
@@ -222,6 +222,11 @@ public class DefaultDashChunkSource implements DashChunkSource {
}
}
+ @Override
+ public void updateTrackSelection(TrackSelection trackSelection) {
+ this.trackSelection = trackSelection;
+ }
+
@Override
public void maybeThrowError() throws IOException {
if (fatalError != null) {
diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsChunkSource.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsChunkSource.java
index 261c9b531c..ee5a5f0809 100644
--- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsChunkSource.java
+++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsChunkSource.java
@@ -183,17 +183,15 @@ import java.util.Map;
}
/**
- * Selects tracks for use.
+ * Sets the current track selection.
*
- * @param trackSelection The track selection.
+ * @param trackSelection The {@link TrackSelection}.
*/
- public void selectTracks(TrackSelection trackSelection) {
+ public void setTrackSelection(TrackSelection trackSelection) {
this.trackSelection = trackSelection;
}
- /**
- * Returns the current track selection.
- */
+ /** Returns the current {@link TrackSelection}. */
public TrackSelection getTrackSelection() {
return trackSelection;
}
diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java
index c8c1b8f566..ff725ec6f7 100644
--- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java
+++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java
@@ -306,14 +306,17 @@ import java.util.Set;
TrackSelection primaryTrackSelection = oldPrimaryTrackSelection;
// Select new tracks.
for (int i = 0; i < selections.length; i++) {
- if (streams[i] == null && selections[i] != null) {
+ TrackSelection selection = selections[i];
+ if (selection == null) {
+ continue;
+ }
+ int trackGroupIndex = trackGroups.indexOf(selection.getTrackGroup());
+ if (trackGroupIndex == primaryTrackGroupIndex) {
+ primaryTrackSelection = selection;
+ chunkSource.setTrackSelection(selection);
+ }
+ if (streams[i] == null) {
enabledTrackGroupCount++;
- TrackSelection selection = selections[i];
- int trackGroupIndex = trackGroups.indexOf(selection.getTrackGroup());
- if (trackGroupIndex == primaryTrackGroupIndex) {
- primaryTrackSelection = selection;
- chunkSource.selectTracks(selection);
- }
streams[i] = new HlsSampleStream(this, trackGroupIndex);
streamResetFlags[i] = true;
if (trackGroupToSampleQueueIndex != null) {
diff --git a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/DefaultSsChunkSource.java b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/DefaultSsChunkSource.java
index 59e18195e2..22dfb04f13 100644
--- a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/DefaultSsChunkSource.java
+++ b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/DefaultSsChunkSource.java
@@ -74,10 +74,10 @@ public class DefaultSsChunkSource implements SsChunkSource {
private final LoaderErrorThrower manifestLoaderErrorThrower;
private final int streamElementIndex;
- private final TrackSelection trackSelection;
private final ChunkExtractorWrapper[] extractorWrappers;
private final DataSource dataSource;
+ private TrackSelection trackSelection;
private SsManifest manifest;
private int currentManifestChunkOffset;
@@ -155,6 +155,11 @@ public class DefaultSsChunkSource implements SsChunkSource {
manifest = newManifest;
}
+ @Override
+ public void updateTrackSelection(TrackSelection trackSelection) {
+ this.trackSelection = trackSelection;
+ }
+
// ChunkSource implementation.
@Override
diff --git a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsChunkSource.java b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsChunkSource.java
index b763a484b8..111393140e 100644
--- a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsChunkSource.java
+++ b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsChunkSource.java
@@ -55,4 +55,11 @@ public interface SsChunkSource extends ChunkSource {
* @param newManifest The new manifest.
*/
void updateManifest(SsManifest newManifest);
+
+ /**
+ * Updates the track selection.
+ *
+ * @param trackSelection The new track selection instance. Must be equivalent to the previous one.
+ */
+ void updateTrackSelection(TrackSelection trackSelection);
}
diff --git a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaPeriod.java b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaPeriod.java
index 286ec82ed6..d103358d37 100644
--- a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaPeriod.java
+++ b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaPeriod.java
@@ -131,6 +131,7 @@ import java.util.List;
stream.release();
streams[i] = null;
} else {
+ stream.getChunkSource().updateTrackSelection(selections[i]);
sampleStreamsList.add(stream);
}
}