Commit 8f3a363d by sofijajvc Committed by Oliver Woodman

Add OpenGL support to av1 extension: Libgav1VideoRenderer

Move reusable code from LibvpxVideoRenderer to SimpleDecoderVideoRenderer.
Pass outputBuffer to renderOutputBuffer method instead of keeping the reference in the renderer.

PiperOrigin-RevId: 272899549
parent 27b90fba
...@@ -28,7 +28,6 @@ import com.google.android.exoplayer2.PlayerMessage.Target; ...@@ -28,7 +28,6 @@ import com.google.android.exoplayer2.PlayerMessage.Target;
import com.google.android.exoplayer2.decoder.SimpleDecoder; import com.google.android.exoplayer2.decoder.SimpleDecoder;
import com.google.android.exoplayer2.drm.DrmSessionManager; import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.drm.ExoMediaCrypto; import com.google.android.exoplayer2.drm.ExoMediaCrypto;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.TraceUtil; import com.google.android.exoplayer2.util.TraceUtil;
import com.google.android.exoplayer2.video.SimpleDecoderVideoRenderer; import com.google.android.exoplayer2.video.SimpleDecoderVideoRenderer;
...@@ -72,13 +71,7 @@ public class LibvpxVideoRenderer extends SimpleDecoderVideoRenderer { ...@@ -72,13 +71,7 @@ public class LibvpxVideoRenderer extends SimpleDecoderVideoRenderer {
private final boolean disableLoopFilter; private final boolean disableLoopFilter;
private final int threads; private final int threads;
private Surface surface;
private VideoDecoderOutputBufferRenderer outputBufferRenderer;
@C.VideoOutputMode private int outputMode;
private VpxDecoder decoder; private VpxDecoder decoder;
private VideoDecoderOutputBuffer outputBuffer;
private VideoFrameMetadataListener frameMetadataListener; private VideoFrameMetadataListener frameMetadataListener;
/** /**
...@@ -197,7 +190,6 @@ public class LibvpxVideoRenderer extends SimpleDecoderVideoRenderer { ...@@ -197,7 +190,6 @@ public class LibvpxVideoRenderer extends SimpleDecoderVideoRenderer {
this.threads = threads; this.threads = threads;
this.numInputBuffers = numInputBuffers; this.numInputBuffers = numInputBuffers;
this.numOutputBuffers = numOutputBuffers; this.numOutputBuffers = numOutputBuffers;
outputMode = C.VIDEO_OUTPUT_MODE_NONE;
} }
@Override @Override
...@@ -236,53 +228,37 @@ public class LibvpxVideoRenderer extends SimpleDecoderVideoRenderer { ...@@ -236,53 +228,37 @@ public class LibvpxVideoRenderer extends SimpleDecoderVideoRenderer {
disableLoopFilter, disableLoopFilter,
enableRowMultiThreadMode, enableRowMultiThreadMode,
threads); threads);
decoder.setOutputMode(outputMode);
TraceUtil.endSection(); TraceUtil.endSection();
return decoder; return decoder;
} }
@Override @Override
@Nullable protected void renderOutputBuffer(
protected VideoDecoderOutputBuffer dequeueOutputBuffer() throws VpxDecoderException { VideoDecoderOutputBuffer outputBuffer, long presentationTimeUs, Format outputFormat)
outputBuffer = decoder.dequeueOutputBuffer(); throws VideoDecoderException {
return outputBuffer;
}
@Override
protected void renderOutputBuffer(long presentationTimeUs, Format outputFormat)
throws VpxDecoderException {
if (frameMetadataListener != null) { if (frameMetadataListener != null) {
frameMetadataListener.onVideoFrameAboutToBeRendered( frameMetadataListener.onVideoFrameAboutToBeRendered(
presentationTimeUs, System.nanoTime(), outputFormat); presentationTimeUs, System.nanoTime(), outputFormat);
} }
super.renderOutputBuffer(outputBuffer, presentationTimeUs, outputFormat);
int bufferMode = outputBuffer.mode;
boolean renderSurface = bufferMode == C.VIDEO_OUTPUT_MODE_SURFACE_YUV && surface != null;
boolean renderYuv = bufferMode == C.VIDEO_OUTPUT_MODE_YUV && outputBufferRenderer != null;
if (!renderYuv && !renderSurface) {
dropOutputBuffer(outputBuffer);
} else {
maybeNotifyVideoSizeChanged(outputBuffer.width, outputBuffer.height);
if (renderYuv) {
outputBufferRenderer.setOutputBuffer(outputBuffer);
// The renderer will release the buffer.
} else { // renderSurface
decoder.renderToSurface(outputBuffer, surface);
outputBuffer.release();
}
onFrameRendered(surface);
}
} }
@Override @Override
protected void clearOutputBuffer() { protected void renderOutputBufferToSurface(VideoDecoderOutputBuffer outputBuffer, Surface surface)
super.clearOutputBuffer(); throws VpxDecoderException {
outputBuffer = null; if (decoder == null) {
throw new VpxDecoderException(
"Failed to render output buffer to surface: decoder is not initialized.");
}
decoder.renderToSurface(outputBuffer, surface);
outputBuffer.release();
} }
@Override @Override
protected boolean hasOutputSurface() { protected void setDecoderOutputMode(@C.VideoOutputMode int outputMode) {
return outputMode != C.VIDEO_OUTPUT_MODE_NONE; if (decoder != null) {
decoder.setOutputMode(outputMode);
}
} }
// PlayerMessage.Target implementation. // PlayerMessage.Target implementation.
...@@ -290,44 +266,13 @@ public class LibvpxVideoRenderer extends SimpleDecoderVideoRenderer { ...@@ -290,44 +266,13 @@ public class LibvpxVideoRenderer extends SimpleDecoderVideoRenderer {
@Override @Override
public void handleMessage(int messageType, @Nullable Object message) throws ExoPlaybackException { public void handleMessage(int messageType, @Nullable Object message) throws ExoPlaybackException {
if (messageType == C.MSG_SET_SURFACE) { if (messageType == C.MSG_SET_SURFACE) {
setOutput((Surface) message, null); setOutputSurface((Surface) message);
} else if (messageType == C.MSG_SET_OUTPUT_BUFFER_RENDERER) { } else if (messageType == C.MSG_SET_OUTPUT_BUFFER_RENDERER) {
setOutput(null, (VideoDecoderOutputBufferRenderer) message); setOutputBufferRenderer((VideoDecoderOutputBufferRenderer) message);
} else if (messageType == C.MSG_SET_VIDEO_FRAME_METADATA_LISTENER) { } else if (messageType == C.MSG_SET_VIDEO_FRAME_METADATA_LISTENER) {
frameMetadataListener = (VideoFrameMetadataListener) message; frameMetadataListener = (VideoFrameMetadataListener) message;
} else { } else {
super.handleMessage(messageType, message); super.handleMessage(messageType, message);
} }
} }
// Internal methods.
private void setOutput(
@Nullable Surface surface, @Nullable VideoDecoderOutputBufferRenderer outputBufferRenderer) {
// At most one output may be non-null. Both may be null if the output is being cleared.
Assertions.checkState(surface == null || outputBufferRenderer == null);
if (this.surface != surface || this.outputBufferRenderer != outputBufferRenderer) {
// The output has changed.
this.surface = surface;
this.outputBufferRenderer = outputBufferRenderer;
if (surface != null) {
outputMode = C.VIDEO_OUTPUT_MODE_SURFACE_YUV;
} else {
outputMode =
outputBufferRenderer != null ? C.VIDEO_OUTPUT_MODE_YUV : C.VIDEO_OUTPUT_MODE_NONE;
}
if (hasOutputSurface()) {
if (decoder != null) {
decoder.setOutputMode(outputMode);
}
onOutputSurfaceChanged();
} else {
// The output has been removed. We leave the outputMode of the underlying decoder unchanged
// in anticipation that a subsequent output will likely be of the same type.
onOutputSurfaceRemoved();
}
} else if (hasOutputSurface()) {
onOutputSurfaceReset(surface);
}
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment