feature: support dynamic bitrate

Change-Id: I362859b52a9d71152ca894ea2ec8aaa2f1f970d1
This commit is contained in:
wetest123 2022-03-16 07:02:39 +00:00 committed by kiwimchen
parent 64a09513ae
commit a86653b0c0
6 changed files with 129 additions and 1 deletions

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}
}

View file

@ -35,7 +35,7 @@ public class ScreenEncoder implements Device.RotationListener {
private final String encoderName;
private final List<CodecOption> 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;
}
}

View file

@ -93,6 +93,8 @@ public final class Server {
controller.getSender().pushClipboardText(text);
}
});
device.setCodecChangeLister(screenEncoder.getCodecChangeLister());
}
try {