From ced5a0b5b40993778694bbbeba5cff54a373cd86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Wed, 2 Feb 2022 02:08:01 +0100 Subject: [PATCH] Catch buffer overflow exceptions in encode, since apparently these can happen. Only seen this when flooding with random, which is... esoteric. So silently swallow this to avoid users deliberately spamming server logs. --- .../blockentity/ProjectorBlockEntity.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/main/java/li/cil/oc2/common/blockentity/ProjectorBlockEntity.java b/src/main/java/li/cil/oc2/common/blockentity/ProjectorBlockEntity.java index 8be564b5..7d8bc759 100644 --- a/src/main/java/li/cil/oc2/common/blockentity/ProjectorBlockEntity.java +++ b/src/main/java/li/cil/oc2/common/blockentity/ProjectorBlockEntity.java @@ -24,6 +24,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import javax.annotation.Nullable; +import java.nio.BufferOverflowException; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.concurrent.ExecutionException; @@ -73,6 +74,7 @@ public final class ProjectorBlockEntity extends ModBlockEntity implements Tickab // Video transfer. private final H264Encoder encoder = new H264Encoder(new CQPRateControl(12)); @Nullable private Future runningEncode; // To allow waiting for previous frame to finish. + private final ByteBuffer encoderBuffer = ByteBuffer.allocateDirect(1024 * 1024); // Re-used decompression buffer. private final Picture picture = Picture.create(ProjectorVMDevice.WIDTH, ProjectorVMDevice.HEIGHT, ColorSpace.YUV420J); private boolean needsIDR = true; // Whether we need to send a keyframe next. @@ -186,12 +188,17 @@ public final class ProjectorBlockEntity extends ModBlockEntity implements Tickab return; } + encoderBuffer.clear(); final ByteBuffer frameData; - if (needsIDR) { - frameData = encoder.encodeIDRFrame(picture, ByteBuffer.allocateDirect(256 * 1024)); - needsIDR = false; - } else { - frameData = encoder.encodeFrame(picture, ByteBuffer.allocateDirect(256 * 1024)).data(); + try { + if (needsIDR) { + frameData = encoder.encodeIDRFrame(picture, encoderBuffer); + needsIDR = false; + } else { + frameData = encoder.encodeFrame(picture, encoderBuffer).data(); + } + } catch (final BufferOverflowException ignored) { + return; // Sad, frame encode failed for unknown reasons... } final Deflater deflater = new Deflater(Deflater.BEST_COMPRESSION);