Add missing equals to MergingMediaPeriod.ForwardingTrackSelection
This causes a bug where the forwarded selections are no longer assumed equal and the child MediaPeriods will think they need to reset streams even though the selection stayed the same. Issue: Issue: google/ExoPlayer#10248 PiperOrigin-RevId: 449454038
This commit is contained in:
parent
dcb58c767c
commit
1a171a004a
@ -12,6 +12,10 @@
|
|||||||
by the user of the device. Apps can opt-out of contributing to platform
|
by the user of the device. Apps can opt-out of contributing to platform
|
||||||
diagnostics for ExoPlayer with
|
diagnostics for ExoPlayer with
|
||||||
`ExoPlayer.Builder.setUsePlatformDiagnostics(false)`.
|
`ExoPlayer.Builder.setUsePlatformDiagnostics(false)`.
|
||||||
|
* Fix bug that tracks are reset too often when using `MergingMediaSource`,
|
||||||
|
for example when side-loading subtitles and changing the selected
|
||||||
|
subtitle mid-playback
|
||||||
|
([#10248](https://github.com/google/ExoPlayer/issues/10248)).
|
||||||
* Track selection:
|
* Track selection:
|
||||||
* Flatten `TrackSelectionOverrides` class into `TrackSelectionParameters`,
|
* Flatten `TrackSelectionOverrides` class into `TrackSelectionParameters`,
|
||||||
and promote `TrackSelectionOverride` to a top level class.
|
and promote `TrackSelectionOverride` to a top level class.
|
||||||
|
@ -608,5 +608,25 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
public boolean isBlacklisted(int index, long nowMs) {
|
public boolean isBlacklisted(int index, long nowMs) {
|
||||||
return trackSelection.isBlacklisted(index, nowMs);
|
return trackSelection.isBlacklisted(index, nowMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(@Nullable Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(o instanceof ForwardingTrackSelection)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ForwardingTrackSelection that = (ForwardingTrackSelection) o;
|
||||||
|
return trackSelection.equals(that.trackSelection) && trackGroup.equals(that.trackGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = 17;
|
||||||
|
result = 31 * result + trackGroup.hashCode();
|
||||||
|
result = 31 * result + trackSelection.hashCode();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ import androidx.media3.exoplayer.upstream.DefaultAllocator;
|
|||||||
import androidx.media3.test.utils.FakeMediaPeriod;
|
import androidx.media3.test.utils.FakeMediaPeriod;
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@ -139,21 +140,64 @@ public final class MergingMediaPeriodTest {
|
|||||||
streams[0].readData(formatHolder, inputBuffer, FLAG_REQUIRE_FORMAT);
|
streams[0].readData(formatHolder, inputBuffer, FLAG_REQUIRE_FORMAT);
|
||||||
streams[1].readData(formatHolder, inputBuffer, FLAG_REQUIRE_FORMAT);
|
streams[1].readData(formatHolder, inputBuffer, FLAG_REQUIRE_FORMAT);
|
||||||
|
|
||||||
FakeMediaPeriodWithSelectTracksPosition childMediaPeriod1 =
|
FakeMediaPeriodWithSelectionParameters childMediaPeriod1 =
|
||||||
(FakeMediaPeriodWithSelectTracksPosition) mergingMediaPeriod.getChildPeriod(0);
|
(FakeMediaPeriodWithSelectionParameters) mergingMediaPeriod.getChildPeriod(0);
|
||||||
assertThat(childMediaPeriod1.selectTracksPositionUs).isEqualTo(0);
|
assertThat(childMediaPeriod1.selectTracksPositionUs).isEqualTo(0);
|
||||||
assertThat(streams[0].readData(formatHolder, inputBuffer, /* readFlags= */ 0))
|
assertThat(streams[0].readData(formatHolder, inputBuffer, /* readFlags= */ 0))
|
||||||
.isEqualTo(C.RESULT_BUFFER_READ);
|
.isEqualTo(C.RESULT_BUFFER_READ);
|
||||||
assertThat(inputBuffer.timeUs).isEqualTo(123_000L);
|
assertThat(inputBuffer.timeUs).isEqualTo(123_000L);
|
||||||
|
|
||||||
FakeMediaPeriodWithSelectTracksPosition childMediaPeriod2 =
|
FakeMediaPeriodWithSelectionParameters childMediaPeriod2 =
|
||||||
(FakeMediaPeriodWithSelectTracksPosition) mergingMediaPeriod.getChildPeriod(1);
|
(FakeMediaPeriodWithSelectionParameters) mergingMediaPeriod.getChildPeriod(1);
|
||||||
assertThat(childMediaPeriod2.selectTracksPositionUs).isEqualTo(3000L);
|
assertThat(childMediaPeriod2.selectTracksPositionUs).isEqualTo(3000L);
|
||||||
assertThat(streams[1].readData(formatHolder, inputBuffer, /* readFlags= */ 0))
|
assertThat(streams[1].readData(formatHolder, inputBuffer, /* readFlags= */ 0))
|
||||||
.isEqualTo(C.RESULT_BUFFER_READ);
|
.isEqualTo(C.RESULT_BUFFER_READ);
|
||||||
assertThat(inputBuffer.timeUs).isEqualTo(456_000 - 3000);
|
assertThat(inputBuffer.timeUs).isEqualTo(456_000 - 3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void selectTracks_withSameArguments_forwardsEqualSelectionsToChildSources()
|
||||||
|
throws Exception {
|
||||||
|
MergingMediaPeriod mergingMediaPeriod =
|
||||||
|
prepareMergingPeriod(
|
||||||
|
new MergingPeriodDefinition(
|
||||||
|
/* timeOffsetUs= */ 0, /* singleSampleTimeUs= */ 0, childFormat11),
|
||||||
|
new MergingPeriodDefinition(
|
||||||
|
/* timeOffsetUs= */ 0, /* singleSampleTimeUs= */ 0, childFormat22));
|
||||||
|
FakeMediaPeriodWithSelectionParameters childMediaPeriod1 =
|
||||||
|
(FakeMediaPeriodWithSelectionParameters) mergingMediaPeriod.getChildPeriod(0);
|
||||||
|
FakeMediaPeriodWithSelectionParameters childMediaPeriod2 =
|
||||||
|
(FakeMediaPeriodWithSelectionParameters) mergingMediaPeriod.getChildPeriod(1);
|
||||||
|
|
||||||
|
TrackGroupArray mergedTrackGroups = mergingMediaPeriod.getTrackGroups();
|
||||||
|
ExoTrackSelection[] selectionArray =
|
||||||
|
new ExoTrackSelection[] {
|
||||||
|
new FixedTrackSelection(mergedTrackGroups.get(0), /* track= */ 0),
|
||||||
|
new FixedTrackSelection(mergedTrackGroups.get(1), /* track= */ 0)
|
||||||
|
};
|
||||||
|
|
||||||
|
mergingMediaPeriod.selectTracks(
|
||||||
|
selectionArray,
|
||||||
|
/* mayRetainStreamFlags= */ new boolean[2],
|
||||||
|
/* streams= */ new SampleStream[2],
|
||||||
|
/* streamResetFlags= */ new boolean[2],
|
||||||
|
/* positionUs= */ 0);
|
||||||
|
ExoTrackSelection firstSelectionChild1 = childMediaPeriod1.selectTracksSelections[0];
|
||||||
|
ExoTrackSelection firstSelectionChild2 = childMediaPeriod2.selectTracksSelections[1];
|
||||||
|
|
||||||
|
mergingMediaPeriod.selectTracks(
|
||||||
|
selectionArray,
|
||||||
|
/* mayRetainStreamFlags= */ new boolean[2],
|
||||||
|
/* streams= */ new SampleStream[2],
|
||||||
|
/* streamResetFlags= */ new boolean[2],
|
||||||
|
/* positionUs= */ 0);
|
||||||
|
ExoTrackSelection secondSelectionChild1 = childMediaPeriod1.selectTracksSelections[0];
|
||||||
|
ExoTrackSelection secondSelectionChild2 = childMediaPeriod2.selectTracksSelections[1];
|
||||||
|
|
||||||
|
assertThat(firstSelectionChild1).isEqualTo(secondSelectionChild1);
|
||||||
|
assertThat(firstSelectionChild2).isEqualTo(secondSelectionChild2);
|
||||||
|
}
|
||||||
|
|
||||||
private MergingMediaPeriod prepareMergingPeriod(MergingPeriodDefinition... definitions)
|
private MergingMediaPeriod prepareMergingPeriod(MergingPeriodDefinition... definitions)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
MediaPeriod[] mediaPeriods = new MediaPeriod[definitions.length];
|
MediaPeriod[] mediaPeriods = new MediaPeriod[definitions.length];
|
||||||
@ -166,7 +210,7 @@ public final class MergingMediaPeriodTest {
|
|||||||
trackGroups[j] = new TrackGroup(definition.formats[j]);
|
trackGroups[j] = new TrackGroup(definition.formats[j]);
|
||||||
}
|
}
|
||||||
mediaPeriods[i] =
|
mediaPeriods[i] =
|
||||||
new FakeMediaPeriodWithSelectTracksPosition(
|
new FakeMediaPeriodWithSelectionParameters(
|
||||||
new TrackGroupArray(trackGroups),
|
new TrackGroupArray(trackGroups),
|
||||||
new EventDispatcher()
|
new EventDispatcher()
|
||||||
.withParameters(
|
.withParameters(
|
||||||
@ -201,11 +245,12 @@ public final class MergingMediaPeriodTest {
|
|||||||
return mergingMediaPeriod;
|
return mergingMediaPeriod;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class FakeMediaPeriodWithSelectTracksPosition extends FakeMediaPeriod {
|
private static final class FakeMediaPeriodWithSelectionParameters extends FakeMediaPeriod {
|
||||||
|
|
||||||
|
public @NullableType ExoTrackSelection[] selectTracksSelections;
|
||||||
public long selectTracksPositionUs;
|
public long selectTracksPositionUs;
|
||||||
|
|
||||||
public FakeMediaPeriodWithSelectTracksPosition(
|
public FakeMediaPeriodWithSelectionParameters(
|
||||||
TrackGroupArray trackGroupArray,
|
TrackGroupArray trackGroupArray,
|
||||||
EventDispatcher mediaSourceEventDispatcher,
|
EventDispatcher mediaSourceEventDispatcher,
|
||||||
TrackDataFactory trackDataFactory) {
|
TrackDataFactory trackDataFactory) {
|
||||||
@ -217,6 +262,7 @@ public final class MergingMediaPeriodTest {
|
|||||||
DrmSessionManager.DRM_UNSUPPORTED,
|
DrmSessionManager.DRM_UNSUPPORTED,
|
||||||
new DrmSessionEventListener.EventDispatcher(),
|
new DrmSessionEventListener.EventDispatcher(),
|
||||||
/* deferOnPrepared= */ false);
|
/* deferOnPrepared= */ false);
|
||||||
|
selectTracksSelections = new ExoTrackSelection[trackGroupArray.length];
|
||||||
selectTracksPositionUs = C.TIME_UNSET;
|
selectTracksPositionUs = C.TIME_UNSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,6 +273,7 @@ public final class MergingMediaPeriodTest {
|
|||||||
@NullableType SampleStream[] streams,
|
@NullableType SampleStream[] streams,
|
||||||
boolean[] streamResetFlags,
|
boolean[] streamResetFlags,
|
||||||
long positionUs) {
|
long positionUs) {
|
||||||
|
selectTracksSelections = Arrays.copyOf(selections, selections.length);
|
||||||
selectTracksPositionUs = positionUs;
|
selectTracksPositionUs = positionUs;
|
||||||
return super.selectTracks(
|
return super.selectTracks(
|
||||||
selections, mayRetainStreamFlags, streams, streamResetFlags, positionUs);
|
selections, mayRetainStreamFlags, streams, streamResetFlags, positionUs);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user