diff --git a/server/src/main/java/com/genymobile/scrcpy/ControlMessage.java b/server/src/main/java/com/genymobile/scrcpy/ControlMessage.java index 99eb805f..a2ce78fb 100644 --- a/server/src/main/java/com/genymobile/scrcpy/ControlMessage.java +++ b/server/src/main/java/com/genymobile/scrcpy/ControlMessage.java @@ -179,4 +179,20 @@ public final class ControlMessage { public long getSequence() { return sequence; } + + public static final int TYPE_REQ_IDR = 100; + public static final int TYPE_SET_BITRATE = 101; + + private int bitRate; + + public int getBitRate() { + return bitRate; + } + + public static ControlMessage createSetBitrate(int bitRate) { + ControlMessage msg = new ControlMessage(); + msg.type = TYPE_SET_BITRATE; + msg.bitRate = bitRate; + return msg; + } } diff --git a/server/src/main/java/com/genymobile/scrcpy/ControlMessageReader.java b/server/src/main/java/com/genymobile/scrcpy/ControlMessageReader.java index 24dc5e50..dbc97e4f 100644 --- a/server/src/main/java/com/genymobile/scrcpy/ControlMessageReader.java +++ b/server/src/main/java/com/genymobile/scrcpy/ControlMessageReader.java @@ -55,6 +55,13 @@ public class ControlMessageReader { int type = buffer.get(); ControlMessage msg; + + msg = preParseMsg(type); + if (msg != null) { + Ln.i("pre parsed msg: " + msg.getType()); + return msg; + } + switch (type) { case ControlMessage.TYPE_INJECT_KEYCODE: msg = parseInjectKeycode(); @@ -210,4 +217,27 @@ public class ControlMessageReader { private static int toUnsigned(byte value) { return value & 0xff; } + + static final int SET_BITRATE_LENGTH = 4; + + private ControlMessage preParseMsg(int type) { + switch(type) { + case ControlMessage.TYPE_REQ_IDR: + Ln.v("pre get msg TYPE_REQ_IDR event"); + return ControlMessage.createEmpty(type); + case ControlMessage.TYPE_SET_BITRATE: + Ln.v("pre get msg TYPE_SET_BITRATE event" ); + return parseSetBitrate(); + default: + return null; + } + } + + private ControlMessage parseSetBitrate() { + if (buffer.remaining() < SET_BITRATE_LENGTH) { + return null; + } + int bitRate = buffer.getInt(); + return ControlMessage.createSetBitrate(bitRate); + } } diff --git a/server/src/main/java/com/genymobile/scrcpy/Controller.java b/server/src/main/java/com/genymobile/scrcpy/Controller.java index 481c512f..e9e6b388 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Controller.java +++ b/server/src/main/java/com/genymobile/scrcpy/Controller.java @@ -80,6 +80,10 @@ public class Controller { private void handleEvent() throws IOException { ControlMessage msg = connection.receiveControlMessage(); + if (preHandlerEvent(msg)) { + Ln.i("pre handled event: " + msg.getType()); + return; + } switch (msg.getType()) { case ControlMessage.TYPE_INJECT_KEYCODE: if (device.supportsInputEvents()) { @@ -312,4 +316,23 @@ public class Controller { return ok; } + + private boolean preHandlerEvent(ControlMessage msg) { + boolean handled = true; + switch(msg.getType()) { + case ControlMessage.TYPE_REQ_IDR: + Ln.i("Device ControlMessage.TYPE_REQ_IDR "); + device.reqIDRFrame(); + break; + case ControlMessage.TYPE_SET_BITRATE: + int bitrate = msg.getBitRate(); + Ln.i("Device ControlMessage.TYPE_SET_BITRATE "); + device.setBitRate(bitrate); + break; + default: + handled = false; + break; + } + return handled; + } } diff --git a/server/src/main/java/com/genymobile/scrcpy/Device.java b/server/src/main/java/com/genymobile/scrcpy/Device.java index 763a7fad..24b374a1 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Device.java +++ b/server/src/main/java/com/genymobile/scrcpy/Device.java @@ -319,4 +319,29 @@ public final class Device { public static Settings getSettings() { return SETTINGS; } + + public interface CodecChangeLister { + void onBitrateChanged(int bitrate); + void onReqIDRFrame(); + } + + private CodecChangeLister codecChangeLister; + + public void setCodecChangeLister(CodecChangeLister listener) { + codecChangeLister = listener; + } + + public void reqIDRFrame() { + Ln.i("do reqIDRFrame: " + codecChangeLister); + if (codecChangeLister != null) { + codecChangeLister.onReqIDRFrame(); + } + } + + public void setBitRate(int bitrate) { + Ln.i("do setBitRate: " + bitrate + codecChangeLister); + if (codecChangeLister != null) { + codecChangeLister.onBitrateChanged(bitrate); + } + } } diff --git a/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java b/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java index 4c23dd92..c5aef439 100644 --- a/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java +++ b/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java @@ -35,7 +35,7 @@ public class ScreenEncoder implements Device.RotationListener { private final String encoderName; private final List codecOptions; - private final int bitRate; + private int bitRate; private final int maxFps; private final boolean sendFrameMeta; private final boolean downsizeOnError; @@ -80,6 +80,7 @@ public class ScreenEncoder implements Device.RotationListener { try { do { MediaCodec codec = createCodec(encoderName); + initCodec(codec); IBinder display = createDisplay(); ScreenInfo screenInfo = device.getScreenInfo(); Rect contentRect = screenInfo.getContentRect(); @@ -293,4 +294,35 @@ public class ScreenEncoder implements Device.RotationListener { private static void destroyDisplay(IBinder display) { SurfaceControl.destroyDisplay(display); } + + private MediaCodec codec; + private Device.CodecChangeLister codecChangeLister; + + private void initCodec(MediaCodec codec) { + this.codec = codec; + } + + public Device.CodecChangeLister getCodecChangeLister() { + if (codecChangeLister == null) { + codecChangeLister = new Device.CodecChangeLister() { + public void onBitrateChanged(int bitrate) { + bitRate = bitrate; + try { + Ln.i("do onBitrateChanged: " + bitrate); + android.os.Bundle b = new android.os.Bundle(); + b.putInt(MediaCodec.PARAMETER_KEY_VIDEO_BITRATE, bitRate); + codec.setParameters(b); + } catch (IllegalStateException e) { + Ln.e("onBitrateChanged failed", e); + } + } + + public void onReqIDRFrame() { + Ln.i("do reqIDRFrame: " + rotationChanged); + rotationChanged.set(true); + } + }; + } + return codecChangeLister; + } } diff --git a/server/src/main/java/com/genymobile/scrcpy/Server.java b/server/src/main/java/com/genymobile/scrcpy/Server.java index 8cf289cd..8547a6c3 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Server.java +++ b/server/src/main/java/com/genymobile/scrcpy/Server.java @@ -93,6 +93,8 @@ public final class Server { controller.getSender().pushClipboardText(text); } }); + + device.setCodecChangeLister(screenEncoder.getCodecChangeLister()); } try {