mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Apply video composition effects in preview
PiperOrigin-RevId: 678207818
This commit is contained in:
parent
c19d910f6b
commit
d8dc513431
@ -121,6 +121,7 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
|
||||
|
||||
private VideoFrameProcessor.@MonotonicNonNull Factory videoFrameProcessorFactory;
|
||||
private PreviewingVideoGraph.@MonotonicNonNull Factory previewingVideoGraphFactory;
|
||||
private List<Effect> compositionEffects;
|
||||
private Clock clock;
|
||||
private boolean built;
|
||||
|
||||
@ -128,6 +129,7 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
|
||||
public Builder(Context context, VideoFrameReleaseControl videoFrameReleaseControl) {
|
||||
this.context = context.getApplicationContext();
|
||||
this.videoFrameReleaseControl = videoFrameReleaseControl;
|
||||
compositionEffects = ImmutableList.of();
|
||||
clock = Clock.DEFAULT;
|
||||
}
|
||||
|
||||
@ -164,6 +166,18 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@linkplain Effect effects} to apply after compositing the sinks' data.
|
||||
*
|
||||
* @param compositionEffects The composition {@linkplain Effect effects}.
|
||||
* @return This builder, for convenience.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
public Builder setCompositionEffects(List<Effect> compositionEffects) {
|
||||
this.compositionEffects = compositionEffects;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link Clock} that will be used.
|
||||
*
|
||||
@ -217,6 +231,8 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
|
||||
private final VideoFrameReleaseControl videoFrameReleaseControl;
|
||||
private final VideoFrameRenderControl videoFrameRenderControl;
|
||||
private final PreviewingVideoGraph.Factory previewingVideoGraphFactory;
|
||||
|
||||
private final List<Effect> compositionEffects;
|
||||
private final Clock clock;
|
||||
private final CopyOnWriteArraySet<PlaybackVideoGraphWrapper.Listener> listeners;
|
||||
|
||||
@ -244,6 +260,7 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
|
||||
videoFrameRenderControl =
|
||||
new VideoFrameRenderControl(new FrameRendererImpl(), videoFrameReleaseControl);
|
||||
previewingVideoGraphFactory = checkStateNotNull(builder.previewingVideoGraphFactory);
|
||||
compositionEffects = builder.compositionEffects;
|
||||
listeners = new CopyOnWriteArraySet<>();
|
||||
state = STATE_CREATED;
|
||||
addListener(videoSinkImpl);
|
||||
@ -642,6 +659,7 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
|
||||
public void setPendingVideoEffects(List<Effect> videoEffects) {
|
||||
this.videoEffects.clear();
|
||||
this.videoEffects.addAll(videoEffects);
|
||||
this.videoEffects.addAll(compositionEffects);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -376,4 +376,42 @@ public class CompositionPlaybackTest {
|
||||
|
||||
assertThat(inputTimestampRecordingShaderProgram.getInputTimestampsUs()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void playback_withCompositionEffect_effectIsApplied() throws Exception {
|
||||
EditedMediaItem editedMediaItem =
|
||||
new EditedMediaItem.Builder(VIDEO_MEDIA_ITEM).setDurationUs(VIDEO_DURATION_US).build();
|
||||
InputTimestampRecordingShaderProgram inputTimestampRecordingShaderProgram =
|
||||
new InputTimestampRecordingShaderProgram();
|
||||
Effect videoEffect = (GlEffect) (context, useHdr) -> inputTimestampRecordingShaderProgram;
|
||||
Composition composition =
|
||||
new Composition.Builder(
|
||||
new EditedMediaItemSequence.Builder(editedMediaItem, editedMediaItem).build())
|
||||
.setEffects(
|
||||
new Effects(
|
||||
/* audioProcessors= */ ImmutableList.of(),
|
||||
/* videoEffects= */ ImmutableList.of(videoEffect)))
|
||||
.build();
|
||||
ImmutableList<Long> expectedTimestampsUs =
|
||||
new ImmutableList.Builder<Long>()
|
||||
.addAll(VIDEO_TIMESTAMPS_US)
|
||||
.addAll(
|
||||
Iterables.transform(
|
||||
VIDEO_TIMESTAMPS_US, timestampUs -> (VIDEO_DURATION_US + timestampUs)))
|
||||
.build();
|
||||
|
||||
getInstrumentation()
|
||||
.runOnMainSync(
|
||||
() -> {
|
||||
player = new CompositionPlayer.Builder(context).build();
|
||||
player.addListener(playerTestListener);
|
||||
player.setComposition(composition);
|
||||
player.prepare();
|
||||
player.play();
|
||||
});
|
||||
playerTestListener.waitUntilPlayerEnded();
|
||||
|
||||
assertThat(inputTimestampRecordingShaderProgram.getInputTimestampsUs())
|
||||
.isEqualTo(expectedTimestampsUs);
|
||||
}
|
||||
}
|
||||
|
@ -673,6 +673,7 @@ public final class CompositionPlayer extends SimpleBasePlayer
|
||||
PlaybackVideoGraphWrapper playbackVideoGraphWrapper =
|
||||
new PlaybackVideoGraphWrapper.Builder(context, videoFrameReleaseControl)
|
||||
.setPreviewingVideoGraphFactory(checkNotNull(previewingVideoGraphFactory))
|
||||
.setCompositionEffects(composition.effects.videoEffects)
|
||||
.setClock(clock)
|
||||
.build();
|
||||
playbackVideoGraphWrapper.addListener(this);
|
||||
|
Loading…
x
Reference in New Issue
Block a user