Rename SequencePlayerRenderersWrapper

Also remove reference to SequencePlayerRenderersWrapper in inner
classes to make them effectively static.

PiperOrigin-RevId: 673720251
This commit is contained in:
kimvde 2024-09-12 00:49:49 -07:00 committed by Copybara-Service
parent f133e8d1f2
commit ce98b7d379
2 changed files with 53 additions and 49 deletions

View File

@ -682,21 +682,21 @@ public final class CompositionPlayer extends SimpleBasePlayer
boolean disableVideoPlayback = shouldDisableVideoPlayback(composition); boolean disableVideoPlayback = shouldDisableVideoPlayback(composition);
for (int i = 0; i < composition.sequences.size(); i++) { for (int i = 0; i < composition.sequences.size(); i++) {
EditedMediaItemSequence editedMediaItemSequence = composition.sequences.get(i); EditedMediaItemSequence editedMediaItemSequence = composition.sequences.get(i);
SequencePlayerRenderersWrapper playerRenderersWrapper = SequenceRenderersFactory sequenceRenderersFactory =
i == 0 i == 0
? SequencePlayerRenderersWrapper.create( ? SequenceRenderersFactory.create(
context, context,
editedMediaItemSequence, editedMediaItemSequence,
playbackAudioGraphWrapper, playbackAudioGraphWrapper,
playbackVideoGraphWrapper.getSink(), playbackVideoGraphWrapper.getSink(),
imageDecoderFactory) imageDecoderFactory)
: SequencePlayerRenderersWrapper.createForAudio( : SequenceRenderersFactory.createForAudio(
context, editedMediaItemSequence, playbackAudioGraphWrapper); context, editedMediaItemSequence, playbackAudioGraphWrapper);
ExoPlayer.Builder playerBuilder = ExoPlayer.Builder playerBuilder =
new ExoPlayer.Builder(context) new ExoPlayer.Builder(context)
.setLooper(getApplicationLooper()) .setLooper(getApplicationLooper())
.setPlaybackLooper(playbackThread.getLooper()) .setPlaybackLooper(playbackThread.getLooper())
.setRenderersFactory(playerRenderersWrapper) .setRenderersFactory(sequenceRenderersFactory)
.setHandleAudioBecomingNoisy(true) .setHandleAudioBecomingNoisy(true)
.setClock(clock); .setClock(clock);

View File

@ -55,8 +55,8 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/** Wraps {@link EditedMediaItemSequence} specific rendering logic and state. */ /** A {@link RenderersFactory} for an {@link EditedMediaItemSequence}. */
/* package */ final class SequencePlayerRenderersWrapper implements RenderersFactory { /* package */ final class SequenceRenderersFactory implements RenderersFactory {
private static final int DEFAULT_FRAME_RATE = 30; private static final int DEFAULT_FRAME_RATE = 30;
@ -66,23 +66,23 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@Nullable private final VideoSink videoSink; @Nullable private final VideoSink videoSink;
@Nullable private final ImageDecoder.Factory imageDecoderFactory; @Nullable private final ImageDecoder.Factory imageDecoderFactory;
/** Creates a renderers wrapper for a player that will play video, image and audio. */ /** Creates a renderers factory for a player that will play video, image and audio. */
public static SequencePlayerRenderersWrapper create( public static SequenceRenderersFactory create(
Context context, Context context,
EditedMediaItemSequence sequence, EditedMediaItemSequence sequence,
PlaybackAudioGraphWrapper playbackAudioGraphWrapper, PlaybackAudioGraphWrapper playbackAudioGraphWrapper,
VideoSink videoSink, VideoSink videoSink,
ImageDecoder.Factory imageDecoderFactory) { ImageDecoder.Factory imageDecoderFactory) {
return new SequencePlayerRenderersWrapper( return new SequenceRenderersFactory(
context, sequence, playbackAudioGraphWrapper, videoSink, imageDecoderFactory); context, sequence, playbackAudioGraphWrapper, videoSink, imageDecoderFactory);
} }
/** Creates a renderers wrapper that for a player that will only play audio. */ /** Creates a renderers factory that for a player that will only play audio. */
public static SequencePlayerRenderersWrapper createForAudio( public static SequenceRenderersFactory createForAudio(
Context context, Context context,
EditedMediaItemSequence sequence, EditedMediaItemSequence sequence,
PlaybackAudioGraphWrapper playbackAudioGraphWrapper) { PlaybackAudioGraphWrapper playbackAudioGraphWrapper) {
return new SequencePlayerRenderersWrapper( return new SequenceRenderersFactory(
context, context,
sequence, sequence,
playbackAudioGraphWrapper, playbackAudioGraphWrapper,
@ -90,7 +90,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/* imageDecoderFactory= */ null); /* imageDecoderFactory= */ null);
} }
private SequencePlayerRenderersWrapper( private SequenceRenderersFactory(
Context context, Context context,
EditedMediaItemSequence sequence, EditedMediaItemSequence sequence,
PlaybackAudioGraphWrapper playbackAudioGraphWrapper, PlaybackAudioGraphWrapper playbackAudioGraphWrapper,
@ -114,10 +114,11 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
renderers.add( renderers.add(
new SequenceAudioRenderer( new SequenceAudioRenderer(
context, context,
/* sequencePlayerRenderersWrapper= */ this,
eventHandler, eventHandler,
audioRendererEventListener, audioRendererEventListener,
playbackAudioGraphWrapper.createInput())); sequence,
/* audioSink= */ playbackAudioGraphWrapper.createInput(),
playbackAudioGraphWrapper));
if (videoSink != null) { if (videoSink != null) {
renderers.add( renderers.add(
@ -125,14 +126,17 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
checkStateNotNull(context), checkStateNotNull(context),
eventHandler, eventHandler,
videoRendererEventListener, videoRendererEventListener,
/* sequencePlayerRenderersWrapper= */ this)); sequence,
renderers.add(new SequenceImageRenderer(/* sequencePlayerRenderersWrapper= */ this)); videoSink));
renderers.add(
new SequenceImageRenderer(sequence, checkStateNotNull(imageDecoderFactory), videoSink));
} }
return renderers.toArray(new Renderer[0]); return renderers.toArray(new Renderer[0]);
} }
private long getOffsetToCompositionTimeUs(int mediaItemIndex, long offsetUs) { private static long getOffsetToCompositionTimeUs(
EditedMediaItemSequence sequence, int mediaItemIndex, long offsetUs) {
// Reverse engineer how timestamps and offsets are computed with a ConcatenatingMediaSource2 // Reverse engineer how timestamps and offsets are computed with a ConcatenatingMediaSource2
// to compute an offset converting buffer timestamps to composition timestamps. // to compute an offset converting buffer timestamps to composition timestamps.
// startPositionUs is not used because it is equal to offsetUs + clipping start time + seek // startPositionUs is not used because it is equal to offsetUs + clipping start time + seek
@ -152,8 +156,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
} }
private static final class SequenceAudioRenderer extends MediaCodecAudioRenderer { private static final class SequenceAudioRenderer extends MediaCodecAudioRenderer {
private final SequencePlayerRenderersWrapper sequencePlayerRenderersWrapper; private final EditedMediaItemSequence sequence;
private final AudioGraphInputAudioSink audioSink; private final AudioGraphInputAudioSink audioSink;
private final PlaybackAudioGraphWrapper playbackAudioGraphWrapper;
@Nullable private EditedMediaItem pendingEditedMediaItem; @Nullable private EditedMediaItem pendingEditedMediaItem;
private long pendingOffsetToCompositionTimeUs; private long pendingOffsetToCompositionTimeUs;
@ -162,13 +167,15 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
// Supplier<EditedMediaItem>) once we finish all the wiring to support multiple sequences. // Supplier<EditedMediaItem>) once we finish all the wiring to support multiple sequences.
public SequenceAudioRenderer( public SequenceAudioRenderer(
Context context, Context context,
SequencePlayerRenderersWrapper sequencePlayerRenderersWrapper,
@Nullable Handler eventHandler, @Nullable Handler eventHandler,
@Nullable AudioRendererEventListener eventListener, @Nullable AudioRendererEventListener eventListener,
AudioGraphInputAudioSink audioSink) { EditedMediaItemSequence sequence,
AudioGraphInputAudioSink audioSink,
PlaybackAudioGraphWrapper playbackAudioGraphWrapper) {
super(context, MediaCodecSelector.DEFAULT, eventHandler, eventListener, audioSink); super(context, MediaCodecSelector.DEFAULT, eventHandler, eventListener, audioSink);
this.sequencePlayerRenderersWrapper = sequencePlayerRenderersWrapper; this.sequence = sequence;
this.audioSink = audioSink; this.audioSink = audioSink;
this.playbackAudioGraphWrapper = playbackAudioGraphWrapper;
} }
// MediaCodecAudioRenderer methods // MediaCodecAudioRenderer methods
@ -177,7 +184,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException { public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
super.render(positionUs, elapsedRealtimeUs); super.render(positionUs, elapsedRealtimeUs);
try { try {
while (sequencePlayerRenderersWrapper.playbackAudioGraphWrapper.processData()) {} while (playbackAudioGraphWrapper.processData()) {}
} catch (ExportException } catch (ExportException
| AudioSink.WriteException | AudioSink.WriteException
| AudioSink.InitializationException | AudioSink.InitializationException
@ -198,10 +205,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
int mediaItemIndex = getTimeline().getIndexOfPeriod(mediaPeriodId.periodUid); int mediaItemIndex = getTimeline().getIndexOfPeriod(mediaPeriodId.periodUid);
// We must first update the pending media item state before calling super.onStreamChanged() // We must first update the pending media item state before calling super.onStreamChanged()
// because the super method will call onProcessedStreamChange() // because the super method will call onProcessedStreamChange()
pendingEditedMediaItem = pendingEditedMediaItem = sequence.editedMediaItems.get(mediaItemIndex);
sequencePlayerRenderersWrapper.sequence.editedMediaItems.get(mediaItemIndex);
pendingOffsetToCompositionTimeUs = pendingOffsetToCompositionTimeUs =
sequencePlayerRenderersWrapper.getOffsetToCompositionTimeUs(mediaItemIndex, offsetUs); getOffsetToCompositionTimeUs(sequence, mediaItemIndex, offsetUs);
super.onStreamChanged(formats, startPositionUs, offsetUs, mediaPeriodId); super.onStreamChanged(formats, startPositionUs, offsetUs, mediaPeriodId);
} }
@ -223,16 +229,16 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
EditedMediaItem currentEditedMediaItem = checkStateNotNull(pendingEditedMediaItem); EditedMediaItem currentEditedMediaItem = checkStateNotNull(pendingEditedMediaItem);
// Use reference equality intentionally. // Use reference equality intentionally.
boolean isLastInSequence = boolean isLastInSequence =
currentEditedMediaItem currentEditedMediaItem == Iterables.getLast(sequence.editedMediaItems);
== Iterables.getLast(sequencePlayerRenderersWrapper.sequence.editedMediaItems);
audioSink.onMediaItemChanged( audioSink.onMediaItemChanged(
currentEditedMediaItem, pendingOffsetToCompositionTimeUs, isLastInSequence); currentEditedMediaItem, pendingOffsetToCompositionTimeUs, isLastInSequence);
} }
} }
private static final class SequenceVideoRenderer extends MediaCodecVideoRenderer { private static final class SequenceVideoRenderer extends MediaCodecVideoRenderer {
private final SequencePlayerRenderersWrapper sequencePlayerRenderersWrapper; private final EditedMediaItemSequence sequence;
private final VideoSink videoSink; private final VideoSink videoSink;
@Nullable private ImmutableList<Effect> pendingEffect; @Nullable private ImmutableList<Effect> pendingEffect;
private long offsetToCompositionTimeUs; private long offsetToCompositionTimeUs;
@ -240,7 +246,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
Context context, Context context,
Handler eventHandler, Handler eventHandler,
VideoRendererEventListener videoRendererEventListener, VideoRendererEventListener videoRendererEventListener,
SequencePlayerRenderersWrapper sequencePlayerRenderersWrapper) { EditedMediaItemSequence sequence,
VideoSink videoSink) {
super( super(
context, context,
MediaCodecAdapter.Factory.getDefault(context), MediaCodecAdapter.Factory.getDefault(context),
@ -251,9 +258,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
videoRendererEventListener, videoRendererEventListener,
MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY, MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY,
/* assumedMinimumCodecOperatingRate= */ DEFAULT_FRAME_RATE, /* assumedMinimumCodecOperatingRate= */ DEFAULT_FRAME_RATE,
checkStateNotNull(sequencePlayerRenderersWrapper.videoSink)); videoSink);
this.sequencePlayerRenderersWrapper = sequencePlayerRenderersWrapper; this.sequence = sequence;
videoSink = checkStateNotNull(sequencePlayerRenderersWrapper.videoSink); this.videoSink = videoSink;
experimentalEnableProcessedStreamChangedAtStart(); experimentalEnableProcessedStreamChangedAtStart();
} }
@ -267,12 +274,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
checkState(getTimeline().getWindowCount() == 1); checkState(getTimeline().getWindowCount() == 1);
super.onStreamChanged(formats, startPositionUs, offsetUs, mediaPeriodId); super.onStreamChanged(formats, startPositionUs, offsetUs, mediaPeriodId);
int mediaItemIndex = getTimeline().getIndexOfPeriod(mediaPeriodId.periodUid); int mediaItemIndex = getTimeline().getIndexOfPeriod(mediaPeriodId.periodUid);
offsetToCompositionTimeUs = offsetToCompositionTimeUs = getOffsetToCompositionTimeUs(sequence, mediaItemIndex, offsetUs);
sequencePlayerRenderersWrapper.getOffsetToCompositionTimeUs(mediaItemIndex, offsetUs); pendingEffect = sequence.editedMediaItems.get(mediaItemIndex).effects.videoEffects;
pendingEffect =
sequencePlayerRenderersWrapper.sequence.editedMediaItems.get(mediaItemIndex)
.effects
.videoEffects;
} }
@Override @Override
@ -291,7 +294,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
} }
private static final class SequenceImageRenderer extends ImageRenderer { private static final class SequenceImageRenderer extends ImageRenderer {
private final SequencePlayerRenderersWrapper sequencePlayerRenderersWrapper;
private final EditedMediaItemSequence sequence;
private final VideoSink videoSink; private final VideoSink videoSink;
private ImmutableList<Effect> videoEffects; private ImmutableList<Effect> videoEffects;
@ -303,11 +307,13 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
private boolean mayRenderStartOfStream; private boolean mayRenderStartOfStream;
private long offsetToCompositionTimeUs; private long offsetToCompositionTimeUs;
public SequenceImageRenderer(SequencePlayerRenderersWrapper sequencePlayerRenderersWrapper) { public SequenceImageRenderer(
super( EditedMediaItemSequence sequence,
checkStateNotNull(sequencePlayerRenderersWrapper.imageDecoderFactory), ImageOutput.NO_OP); ImageDecoder.Factory imageDecoderFactory,
this.sequencePlayerRenderersWrapper = sequencePlayerRenderersWrapper; VideoSink videoSink) {
videoSink = checkStateNotNull(sequencePlayerRenderersWrapper.videoSink); super(imageDecoderFactory, ImageOutput.NO_OP);
this.sequence = sequence;
this.videoSink = videoSink;
videoEffects = ImmutableList.of(); videoEffects = ImmutableList.of();
streamStartPositionUs = C.TIME_UNSET; streamStartPositionUs = C.TIME_UNSET;
} }
@ -396,10 +402,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
super.onStreamChanged(formats, startPositionUs, offsetUs, mediaPeriodId); super.onStreamChanged(formats, startPositionUs, offsetUs, mediaPeriodId);
streamStartPositionUs = startPositionUs; streamStartPositionUs = startPositionUs;
int mediaItemIndex = getTimeline().getIndexOfPeriod(mediaPeriodId.periodUid); int mediaItemIndex = getTimeline().getIndexOfPeriod(mediaPeriodId.periodUid);
editedMediaItem = editedMediaItem = sequence.editedMediaItems.get(mediaItemIndex);
sequencePlayerRenderersWrapper.sequence.editedMediaItems.get(mediaItemIndex); offsetToCompositionTimeUs = getOffsetToCompositionTimeUs(sequence, mediaItemIndex, offsetUs);
offsetToCompositionTimeUs =
sequencePlayerRenderersWrapper.getOffsetToCompositionTimeUs(mediaItemIndex, offsetUs);
timestampIterator = createTimestampIterator(/* positionUs= */ startPositionUs); timestampIterator = createTimestampIterator(/* positionUs= */ startPositionUs);
videoEffects = editedMediaItem.effects.videoEffects; videoEffects = editedMediaItem.effects.videoEffects;
inputStreamPending = true; inputStreamPending = true;