diff options
Diffstat (limited to 'app/src/main/java/invalid/lena/scrcpy/VideoStream.java')
| -rw-r--r-- | app/src/main/java/invalid/lena/scrcpy/VideoStream.java | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/app/src/main/java/invalid/lena/scrcpy/VideoStream.java b/app/src/main/java/invalid/lena/scrcpy/VideoStream.java index 7ecb3f1..9d870e5 100644 --- a/app/src/main/java/invalid/lena/scrcpy/VideoStream.java +++ b/app/src/main/java/invalid/lena/scrcpy/VideoStream.java @@ -34,11 +34,11 @@ public final class VideoStream { private static final int FLAG_SESSION_INT_BIT = 0x80000000; private static final int MAX_FRAME_SIZE = 8 * 1024 * 1024; + private static final int MAX_DIMENSION = 16 * 1024; private final InputStream source; private final VideoFrames sink; private final SizeListener sizeListener; - private volatile VideoRecorder recorder; // optional tap private volatile Runnable onEnd; // fired once when run() exits private Thread thread; private volatile boolean stop; @@ -69,10 +69,6 @@ public final class VideoStream { catch (InterruptedException e) { Thread.currentThread().interrupt(); } } - public void setRecorder(VideoRecorder r) { - this.recorder = r; - } - // Fired exactly once, on the reader thread, when run() exits - whether // by EOF, error, or stop(). The video socket is the authoritative // stream: when it ends mid-session the link is gone, so Session uses @@ -89,6 +85,10 @@ public final class VideoStream { fourcc = Wire.readBe32(four, 0); if (fourcc == 0) throw new IOException("video: server reports stream disabled"); if (fourcc == 1) throw new IOException("video: server reports configuration error"); + if (fourcc != Wire.CODEC_H264 && fourcc != Wire.CODEC_H265 + && fourcc != Wire.CODEC_AV1) { + throw new IOException("video: unexpected codec " + Wire.fourccName(fourcc)); + } Log.i("video meta codec=%s", Wire.fourccName(fourcc)); byte[] tail8 = new byte[8]; @@ -117,9 +117,15 @@ public final class VideoStream { } private void parseSessionMeta(int hi, byte[] tail8) throws IOException { + if ((hi & ~0x80000001) != 0) { + throw new IOException("video session meta has unknown flags"); + } Wire.readFully(source, tail8); int newW = Wire.readBe32(tail8, 0); int newH = Wire.readBe32(tail8, 4); + if (newW < 1 || newW > MAX_DIMENSION || newH < 1 || newH > MAX_DIMENSION) { + throw new IOException("video size out of range: " + newW + "x" + newH); + } boolean clientResize = (hi & 1) != 0; Log.i("video session meta %dx%d client_resize=%s", newW, newH, clientResize); @@ -133,16 +139,14 @@ public final class VideoStream { sink.reconfigure(fourcc, curW, curH); } if (sizeListener != null) sizeListener.onSize(curW, curH); - VideoRecorder r = recorder; - if (r != null) r.onMeta(fourcc, curW, curH); } private void parseFrame(int hi, byte[] tail8) throws IOException { Wire.readFully(source, tail8); long pts = ((long) hi << 32) | (Wire.readBe32(tail8, 0) & 0xffffffffL); int size = Wire.readBe32(tail8, 4); - boolean cfg = (pts & FLAG_CONFIG) != 0; - boolean key = (pts & FLAG_KEYFRAME) != 0; + boolean cfg = (pts & FLAG_CONFIG) != 0; + boolean keyframe = (pts & FLAG_KEYFRAME) != 0; long ptsUs = pts & PTS_MASK; if (size <= 0 || size > MAX_FRAME_SIZE) { @@ -154,8 +158,6 @@ public final class VideoStream { byte[] payload = new byte[size]; Wire.readFully(source, payload); - sink.feed(payload, ptsUs, cfg); - VideoRecorder r = recorder; - if (r != null) r.onFrame(payload, ptsUs, cfg, key); + sink.feed(payload, ptsUs, cfg, keyframe); } } |