From 25feac7664dd1c99992c0df0e7613722029f5111 Mon Sep 17 00:00:00 2001 From: Colin Kho Date: Tue, 22 Apr 2025 11:38:38 -0700 Subject: [PATCH] Add ForwardingTrackSelection to allow access to the underlying instance --- .../exoplayer/source/MergingMediaPeriod.java | 65 ++++--- .../ForwardingTrackSelection.java | 181 ++++++++++++++++++ 2 files changed, 213 insertions(+), 33 deletions(-) create mode 100644 libraries/exoplayer/src/main/java/androidx/media3/exoplayer/trackselection/ForwardingTrackSelection.java diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/MergingMediaPeriod.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/MergingMediaPeriod.java index 48b94c2040..4a3cf8412f 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/MergingMediaPeriod.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/MergingMediaPeriod.java @@ -29,6 +29,7 @@ import androidx.media3.exoplayer.source.chunk.Chunk; import androidx.media3.exoplayer.source.chunk.MediaChunk; import androidx.media3.exoplayer.source.chunk.MediaChunkIterator; import androidx.media3.exoplayer.trackselection.ExoTrackSelection; +import androidx.media3.exoplayer.trackselection.ForwardingTrackSelection; import com.google.common.collect.Lists; import java.io.IOException; import java.util.ArrayList; @@ -140,7 +141,7 @@ import java.util.List; TrackGroup mergedTrackGroup = mergedTrackSelection.getTrackGroup(); TrackGroup childTrackGroup = checkNotNull(childTrackGroupByMergedTrackGroup.get(mergedTrackGroup)); - childSelections[j] = new ForwardingTrackSelection(mergedTrackSelection, childTrackGroup); + childSelections[j] = new MergingMediaPeriodTrackSelection(mergedTrackSelection, childTrackGroup); } else { childSelections[j] = null; } @@ -313,19 +314,17 @@ import java.util.List; Assertions.checkNotNull(callback).onContinueLoadingRequested(this); } - private static final class ForwardingTrackSelection implements ExoTrackSelection { - - private final ExoTrackSelection trackSelection; + private static final class MergingMediaPeriodTrackSelection extends ForwardingTrackSelection { private final TrackGroup trackGroup; - public ForwardingTrackSelection(ExoTrackSelection trackSelection, TrackGroup trackGroup) { - this.trackSelection = trackSelection; + public MergingMediaPeriodTrackSelection(ExoTrackSelection trackSelection, TrackGroup trackGroup) { + super(trackSelection); this.trackGroup = trackGroup; } @Override public @Type int getType() { - return trackSelection.getType(); + return getWrappedInstance().getType(); } @Override @@ -335,83 +334,83 @@ import java.util.List; @Override public int length() { - return trackSelection.length(); + return getWrappedInstance().length(); } @Override public Format getFormat(int index) { - return trackGroup.getFormat(trackSelection.getIndexInTrackGroup(index)); + return trackGroup.getFormat(getWrappedInstance().getIndexInTrackGroup(index)); } @Override public int getIndexInTrackGroup(int index) { - return trackSelection.getIndexInTrackGroup(index); + return getWrappedInstance().getIndexInTrackGroup(index); } @Override public int indexOf(Format format) { - return trackSelection.indexOf(trackGroup.indexOf(format)); + return getWrappedInstance().indexOf(trackGroup.indexOf(format)); } @Override public int indexOf(int indexInTrackGroup) { - return trackSelection.indexOf(indexInTrackGroup); + return getWrappedInstance().indexOf(indexInTrackGroup); } @Override public void enable() { - trackSelection.enable(); + getWrappedInstance().enable(); } @Override public void disable() { - trackSelection.disable(); + getWrappedInstance().disable(); } @Override public Format getSelectedFormat() { - return trackGroup.getFormat(trackSelection.getSelectedIndexInTrackGroup()); + return trackGroup.getFormat(getWrappedInstance().getSelectedIndexInTrackGroup()); } @Override public int getSelectedIndexInTrackGroup() { - return trackSelection.getSelectedIndexInTrackGroup(); + return getWrappedInstance().getSelectedIndexInTrackGroup(); } @Override public int getSelectedIndex() { - return trackSelection.getSelectedIndex(); + return getWrappedInstance().getSelectedIndex(); } @Override public @C.SelectionReason int getSelectionReason() { - return trackSelection.getSelectionReason(); + return getWrappedInstance().getSelectionReason(); } @Nullable @Override public Object getSelectionData() { - return trackSelection.getSelectionData(); + return getWrappedInstance().getSelectionData(); } @Override public void onPlaybackSpeed(float playbackSpeed) { - trackSelection.onPlaybackSpeed(playbackSpeed); + getWrappedInstance().onPlaybackSpeed(playbackSpeed); } @Override public void onDiscontinuity() { - trackSelection.onDiscontinuity(); + getWrappedInstance().onDiscontinuity(); } @Override public void onRebuffer() { - trackSelection.onRebuffer(); + getWrappedInstance().onRebuffer(); } @Override public void onPlayWhenReadyChanged(boolean playWhenReady) { - trackSelection.onPlayWhenReadyChanged(playWhenReady); + getWrappedInstance().onPlayWhenReadyChanged(playWhenReady); } @Override @@ -421,34 +420,34 @@ import java.util.List; long availableDurationUs, List queue, MediaChunkIterator[] mediaChunkIterators) { - trackSelection.updateSelectedTrack( + getWrappedInstance().updateSelectedTrack( playbackPositionUs, bufferedDurationUs, availableDurationUs, queue, mediaChunkIterators); } @Override public int evaluateQueueSize(long playbackPositionUs, List queue) { - return trackSelection.evaluateQueueSize(playbackPositionUs, queue); + return getWrappedInstance().evaluateQueueSize(playbackPositionUs, queue); } @Override public boolean shouldCancelChunkLoad( long playbackPositionUs, Chunk loadingChunk, List queue) { - return trackSelection.shouldCancelChunkLoad(playbackPositionUs, loadingChunk, queue); + return getWrappedInstance().shouldCancelChunkLoad(playbackPositionUs, loadingChunk, queue); } @Override public boolean excludeTrack(int index, long exclusionDurationMs) { - return trackSelection.excludeTrack(index, exclusionDurationMs); + return getWrappedInstance().excludeTrack(index, exclusionDurationMs); } @Override public boolean isTrackExcluded(int index, long nowMs) { - return trackSelection.isTrackExcluded(index, nowMs); + return getWrappedInstance().isTrackExcluded(index, nowMs); } @Override public long getLatestBitrateEstimate() { - return trackSelection.getLatestBitrateEstimate(); + return getWrappedInstance().getLatestBitrateEstimate(); } @Override @@ -456,18 +455,18 @@ import java.util.List; if (this == o) { return true; } - if (!(o instanceof ForwardingTrackSelection)) { + if (!(o instanceof MergingMediaPeriodTrackSelection)) { return false; } - ForwardingTrackSelection that = (ForwardingTrackSelection) o; - return trackSelection.equals(that.trackSelection) && trackGroup.equals(that.trackGroup); + MergingMediaPeriodTrackSelection that = (MergingMediaPeriodTrackSelection) o; + return getWrappedInstance().equals(that.getWrappedInstance()) && trackGroup.equals(that.trackGroup); } @Override public int hashCode() { int result = 17; result = 31 * result + trackGroup.hashCode(); - result = 31 * result + trackSelection.hashCode(); + result = 31 * result + getWrappedInstance().hashCode(); return result; } } diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/trackselection/ForwardingTrackSelection.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/trackselection/ForwardingTrackSelection.java new file mode 100644 index 0000000000..5788540ec8 --- /dev/null +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/trackselection/ForwardingTrackSelection.java @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package androidx.media3.exoplayer.trackselection; + +import androidx.annotation.Nullable; +import androidx.media3.common.C; +import androidx.media3.common.Format; +import androidx.media3.common.TrackGroup; +import androidx.media3.common.util.UnstableApi; +import androidx.media3.exoplayer.source.chunk.Chunk; +import androidx.media3.exoplayer.source.chunk.MediaChunk; +import androidx.media3.exoplayer.source.chunk.MediaChunkIterator; +import java.util.List; + +@UnstableApi +public class ForwardingTrackSelection implements ExoTrackSelection { + private final ExoTrackSelection trackSelection; + + public ForwardingTrackSelection(ExoTrackSelection trackSelection) { + this.trackSelection = trackSelection; + } + + @Override + public void enable() { + trackSelection.enable(); + } + + @Override + public void disable() { + trackSelection.disable(); + } + + @Override + public Format getSelectedFormat() { + return trackSelection.getSelectedFormat(); + } + + @Override + public int getSelectedIndexInTrackGroup() { + return trackSelection.getSelectedIndexInTrackGroup(); + } + + @Override + public int getSelectedIndex() { + return trackSelection.getSelectedIndex(); + } + + @Override + public @C.SelectionReason int getSelectionReason() { + return trackSelection.getSelectionReason(); + } + + @Nullable + @Override + public Object getSelectionData() { + return trackSelection.getSelectionData(); + } + + @Override + public void onPlaybackSpeed(float playbackSpeed) { + trackSelection.onPlaybackSpeed(playbackSpeed); + } + + @Override + public void onDiscontinuity() { + trackSelection.onDiscontinuity(); + } + + @Override + public void onRebuffer() { + trackSelection.onRebuffer(); + } + + @Override + public void onPlayWhenReadyChanged(boolean playWhenReady) { + trackSelection.onPlayWhenReadyChanged(playWhenReady); + } + + @Override + public void updateSelectedTrack(long playbackPositionUs, long bufferedDurationUs, + long availableDurationUs, List queue, + MediaChunkIterator[] mediaChunkIterators) { + trackSelection.updateSelectedTrack(playbackPositionUs, bufferedDurationUs, + availableDurationUs, queue, mediaChunkIterators); + } + + @Override + public int evaluateQueueSize(long playbackPositionUs, List queue) { + return trackSelection.evaluateQueueSize(playbackPositionUs, queue); + } + + @Override + public boolean shouldCancelChunkLoad(long playbackPositionUs, Chunk loadingChunk, + List queue) { + return trackSelection.shouldCancelChunkLoad(playbackPositionUs, loadingChunk, queue); + } + + @Override + public boolean excludeTrack(int index, long exclusionDurationMs) { + return trackSelection.excludeTrack(index, exclusionDurationMs); + } + + @Override + public boolean isTrackExcluded(int index, long nowMs) { + return trackSelection.isTrackExcluded(index, nowMs); + } + + @Override + public long getLatestBitrateEstimate() { + return trackSelection.getLatestBitrateEstimate(); + } + + @Override + public @Type int getType() { + return trackSelection.getType(); + } + + @Override + public TrackGroup getTrackGroup() { + return trackSelection.getTrackGroup(); + } + + @Override + public int length() { + return trackSelection.length(); + } + + @Override + public Format getFormat(int index) { + return trackSelection.getFormat(index); + } + + @Override + public int getIndexInTrackGroup(int index) { + return trackSelection.getIndexInTrackGroup(index); + } + + @Override + public int indexOf(Format format) { + return trackSelection.indexOf(format); + } + + @Override + public int indexOf(int indexInTrackGroup) { + return trackSelection.indexOf(indexInTrackGroup); + } + + public ExoTrackSelection getWrappedInstance() { + return trackSelection; + } + + public int hashCode() { + return getWrappedInstance().hashCode(); + } + + @Override + public boolean equals(@Nullable Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + ForwardingTrackSelection other = (ForwardingTrackSelection) obj; + + return getWrappedInstance().equals(other.getWrappedInstance()); + } +}