Fix getChildPeriod logic if the child is a TimeOffsetMediaPeriod

The current instanceof check accidentally unpacks the child,
returning the inner period instead of the one passed to the source.

PiperOrigin-RevId: 746556825
This commit is contained in:
tonihei 2025-04-11 12:43:21 -07:00 committed by Copybara-Service
parent 21faf85382
commit 68538029c9
2 changed files with 39 additions and 1 deletions

View File

@ -41,6 +41,7 @@ import java.util.List;
/* package */ final class MergingMediaPeriod implements MediaPeriod, MediaPeriod.Callback {
private final MediaPeriod[] periods;
private final boolean[] periodsWithTimeOffsets;
private final IdentityHashMap<SampleStream, Integer> streamPeriodIndices;
private final CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory;
private final ArrayList<MediaPeriod> childrenPendingPreparation;
@ -62,8 +63,10 @@ import java.util.List;
compositeSequenceableLoader = compositeSequenceableLoaderFactory.empty();
streamPeriodIndices = new IdentityHashMap<>();
enabledPeriods = new MediaPeriod[0];
periodsWithTimeOffsets = new boolean[periods.length];
for (int i = 0; i < periods.length; i++) {
if (periodTimeOffsetsUs[i] != 0) {
periodsWithTimeOffsets[i] = true;
this.periods[i] = new TimeOffsetMediaPeriod(periods[i], periodTimeOffsetsUs[i]);
}
}
@ -75,7 +78,7 @@ import java.util.List;
* specified index.
*/
public MediaPeriod getChildPeriod(int index) {
return periods[index] instanceof TimeOffsetMediaPeriod
return periodsWithTimeOffsets[index]
? ((TimeOffsetMediaPeriod) periods[index]).getWrappedMediaPeriod()
: periods[index];
}

View File

@ -22,6 +22,7 @@ import static com.google.common.truth.Truth.assertThat;
import androidx.media3.common.C;
import androidx.media3.common.Format;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.TrackGroup;
import androidx.media3.common.util.NullableType;
import androidx.media3.decoder.DecoderInputBuffer;
@ -33,6 +34,7 @@ import androidx.media3.exoplayer.source.MediaSource.MediaPeriodId;
import androidx.media3.exoplayer.source.MediaSourceEventListener.EventDispatcher;
import androidx.media3.exoplayer.trackselection.ExoTrackSelection;
import androidx.media3.exoplayer.trackselection.FixedTrackSelection;
import androidx.media3.exoplayer.upstream.Allocator;
import androidx.media3.exoplayer.upstream.DefaultAllocator;
import androidx.media3.test.utils.FakeMediaPeriod;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@ -270,6 +272,39 @@ public final class MergingMediaPeriodTest {
assertThat(inputBuffer.timeUs).isEqualTo(456_000 - 3000);
}
@Test
public void
getChildPeriod_withTimeOffsetsAndTimeOffsetPeriodChildren_returnsCorrectChildPeriod() {
TrackGroupArray trackGroupArray =
new TrackGroupArray(
new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_AV1).build()));
Allocator allocator =
new DefaultAllocator(/* trimOnReset= */ false, /* individualAllocationSize= */ 1024);
MediaPeriod childPeriod0 =
new FakeMediaPeriod(
trackGroupArray, allocator, /* singleSampleTimeUs= */ 0, new EventDispatcher());
MediaPeriod childPeriod1 =
new TimeOffsetMediaPeriod(
new FakeMediaPeriod(
trackGroupArray, allocator, /* singleSampleTimeUs= */ 300, new EventDispatcher()),
/* timeOffsetUs= */ -300);
MediaPeriod childPeriod2 =
new FakeMediaPeriod(
trackGroupArray, allocator, /* singleSampleTimeUs= */ -500, new EventDispatcher());
MergingMediaPeriod mergingMediaPeriod =
new MergingMediaPeriod(
new DefaultCompositeSequenceableLoaderFactory(),
/* periodTimeOffsetsUs= */ new long[] {0, 0, 500},
childPeriod0,
childPeriod1,
childPeriod2);
assertThat(mergingMediaPeriod.getChildPeriod(0)).isEqualTo(childPeriod0);
assertThat(mergingMediaPeriod.getChildPeriod(1)).isEqualTo(childPeriod1);
assertThat(mergingMediaPeriod.getChildPeriod(2)).isEqualTo(childPeriod2);
}
private MergingMediaPeriod prepareMergingPeriod(MergingPeriodDefinition... definitions)
throws Exception {
return prepareMergingPeriod(/* singleTrackGroup= */ false, definitions);