Add DefaultVideoSink and implement straightforward methods

Other methods will be implemented in follow-up CLs

PiperOrigin-RevId: 683538245
This commit is contained in:
kimvde 2024-10-08 02:46:22 -07:00 committed by Copybara-Service
parent 8d0b82dfc3
commit 7c9fede3ad
2 changed files with 192 additions and 12 deletions

View File

@ -0,0 +1,181 @@
/*
* Copyright 2024 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
*
* https://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.video;
import android.graphics.Bitmap;
import android.view.Surface;
import androidx.media3.common.Effect;
import androidx.media3.common.Format;
import androidx.media3.common.util.Size;
import androidx.media3.common.util.TimestampIterator;
import java.util.List;
import java.util.concurrent.Executor;
/**
* The default {@link VideoSink} implementation. This implementation renders video frames to an
* output surface. Applying {@linkplain Effect video effects} is unsupported.
*/
/* package */ final class DefaultVideoSink implements VideoSink {
private final VideoFrameReleaseControl videoFrameReleaseControl;
private final VideoFrameRenderControl videoFrameRenderControl;
public DefaultVideoSink(
VideoFrameReleaseControl videoFrameReleaseControl,
VideoFrameRenderControl videoFrameRenderControl) {
this.videoFrameReleaseControl = videoFrameReleaseControl;
this.videoFrameRenderControl = videoFrameRenderControl;
}
@Override
public void onRendererEnabled(boolean mayRenderStartOfStream) {
videoFrameReleaseControl.onEnabled(mayRenderStartOfStream);
}
@Override
public void onRendererDisabled() {
videoFrameReleaseControl.onDisabled();
}
@Override
public void onRendererStarted() {
videoFrameReleaseControl.onStarted();
}
@Override
public void onRendererStopped() {
videoFrameReleaseControl.onStopped();
}
@Override
public void setListener(Listener listener, Executor executor) {
throw new UnsupportedOperationException();
}
@Override
public void initialize(Format sourceFormat) {
throw new UnsupportedOperationException();
}
@Override
public boolean isInitialized() {
throw new UnsupportedOperationException();
}
@Override
public void flush(boolean resetPosition) {
if (resetPosition) {
videoFrameReleaseControl.reset();
}
}
@Override
public boolean isReady(boolean rendererOtherwiseReady) {
throw new UnsupportedOperationException();
}
@Override
public boolean isEnded() {
throw new UnsupportedOperationException();
}
@Override
public Surface getInputSurface() {
throw new UnsupportedOperationException();
}
@Override
public void setVideoFrameMetadataListener(VideoFrameMetadataListener videoFrameMetadataListener) {
throw new UnsupportedOperationException();
}
@Override
public void setPlaybackSpeed(float speed) {
videoFrameRenderControl.setPlaybackSpeed(speed);
}
@Override
public void setVideoEffects(List<Effect> videoEffects) {
throw new UnsupportedOperationException();
}
@Override
public void setPendingVideoEffects(List<Effect> videoEffects) {
throw new UnsupportedOperationException();
}
@Override
public void setStreamTimestampInfo(
long streamStartPositionUs,
long streamOffsetUs,
long bufferTimestampAdjustmentUs,
long lastResetPositionUs) {
throw new UnsupportedOperationException();
}
@Override
public void setOutputSurfaceInfo(Surface outputSurface, Size outputResolution) {
throw new UnsupportedOperationException();
}
@Override
public void clearOutputSurfaceInfo() {
throw new UnsupportedOperationException();
}
@Override
public void setChangeFrameRateStrategy(int changeFrameRateStrategy) {
videoFrameReleaseControl.setChangeFrameRateStrategy(changeFrameRateStrategy);
}
@Override
public void enableMayRenderStartOfStream() {
videoFrameReleaseControl.allowReleaseFirstFrameBeforeStarted();
}
@Override
public void onInputStreamChanged(@InputType int inputType, Format format) {
throw new UnsupportedOperationException();
}
@Override
public boolean handleInputFrame(
long framePresentationTimeUs,
boolean isLastFrame,
long positionUs,
long elapsedRealtimeUs,
VideoFrameHandler videoFrameHandler) {
throw new UnsupportedOperationException();
}
@Override
public boolean handleInputBitmap(Bitmap inputBitmap, TimestampIterator timestampIterator) {
throw new UnsupportedOperationException();
}
@Override
public void render(long positionUs, long elapsedRealtimeUs) {
throw new UnsupportedOperationException();
}
@Override
public void join(boolean renderNextFrameImmediately) {
videoFrameReleaseControl.join(renderNextFrameImmediately);
}
@Override
public void release() {}
}

View File

@ -231,8 +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 VideoSink defaultVideoSink;
private final Clock clock;
private final CopyOnWriteArraySet<PlaybackVideoGraphWrapper.Listener> listeners;
@ -261,6 +261,7 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
new VideoFrameRenderControl(new FrameRendererImpl(), videoFrameReleaseControl);
previewingVideoGraphFactory = checkStateNotNull(builder.previewingVideoGraphFactory);
compositionEffects = builder.compositionEffects;
defaultVideoSink = new DefaultVideoSink(videoFrameReleaseControl, videoFrameRenderControl);
listeners = new CopyOnWriteArraySet<>();
state = STATE_CREATED;
addListener(inputVideoSink);
@ -465,7 +466,7 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
}
private void setPlaybackSpeed(float speed) {
videoFrameRenderControl.setPlaybackSpeed(speed);
defaultVideoSink.setPlaybackSpeed(speed);
}
private void onStreamOffsetChange(
@ -529,22 +530,22 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
@Override
public void onRendererEnabled(boolean mayRenderStartOfStream) {
videoFrameReleaseControl.onEnabled(mayRenderStartOfStream);
defaultVideoSink.onRendererEnabled(mayRenderStartOfStream);
}
@Override
public void onRendererDisabled() {
videoFrameReleaseControl.onDisabled();
defaultVideoSink.onRendererDisabled();
}
@Override
public void onRendererStarted() {
videoFrameReleaseControl.onStarted();
defaultVideoSink.onRendererStarted();
}
@Override
public void onRendererStopped() {
videoFrameReleaseControl.onStopped();
defaultVideoSink.onRendererStopped();
}
@Override
@ -574,9 +575,7 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
finalBufferPresentationTimeUs = C.TIME_UNSET;
lastBufferPresentationTimeUs = C.TIME_UNSET;
PlaybackVideoGraphWrapper.this.flush();
if (resetPosition) {
videoFrameReleaseControl.reset();
}
defaultVideoSink.flush(resetPosition);
pendingInputStreamBufferPresentationTimeUs = C.TIME_UNSET;
// Don't change input stream offset or reset the pending input stream offset change so that
// it's announced with the next input frame.
@ -689,12 +688,12 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
@Override
public void setChangeFrameRateStrategy(
@C.VideoChangeFrameRateStrategy int changeFrameRateStrategy) {
videoFrameReleaseControl.setChangeFrameRateStrategy(changeFrameRateStrategy);
defaultVideoSink.setChangeFrameRateStrategy(changeFrameRateStrategy);
}
@Override
public void enableMayRenderStartOfStream() {
videoFrameReleaseControl.allowReleaseFirstFrameBeforeStarted();
defaultVideoSink.enableMayRenderStartOfStream();
}
@Override
@ -820,7 +819,7 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
@Override
public void join(boolean renderNextFrameImmediately) {
videoFrameReleaseControl.join(renderNextFrameImmediately);
defaultVideoSink.join(renderNextFrameImmediately);
}
@Override