mirror of
https://github.com/Genymobile/scrcpy.git
synced 2025-08-05 23:59:01 +00:00
allow requesting IDR frames through the control channel
This commit is contained in:
parent
c27d116a66
commit
48b780e95b
5 changed files with 34 additions and 0 deletions
|
@ -156,6 +156,7 @@ public final class Server {
|
||||||
|
|
||||||
if (controller != null) {
|
if (controller != null) {
|
||||||
controller.setSurfaceCapture(surfaceCapture);
|
controller.setSurfaceCapture(surfaceCapture);
|
||||||
|
controller.setSurfaceEncoder(surfaceEncoder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ public final class ControlMessage {
|
||||||
public static final int TYPE_OPEN_HARD_KEYBOARD_SETTINGS = 15;
|
public static final int TYPE_OPEN_HARD_KEYBOARD_SETTINGS = 15;
|
||||||
public static final int TYPE_START_APP = 16;
|
public static final int TYPE_START_APP = 16;
|
||||||
public static final int TYPE_RESET_VIDEO = 17;
|
public static final int TYPE_RESET_VIDEO = 17;
|
||||||
|
public static final int TYPE_REQUEST_IDR = 18;
|
||||||
|
|
||||||
public static final long SEQUENCE_INVALID = 0;
|
public static final long SEQUENCE_INVALID = 0;
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,8 @@ public class ControlMessageReader {
|
||||||
return parseUhidDestroy();
|
return parseUhidDestroy();
|
||||||
case ControlMessage.TYPE_START_APP:
|
case ControlMessage.TYPE_START_APP:
|
||||||
return parseStartApp();
|
return parseStartApp();
|
||||||
|
case ControlMessage.TYPE_REQUEST_IDR:
|
||||||
|
return ControlMessage.createEmpty(type);
|
||||||
default:
|
default:
|
||||||
throw new ControlProtocolException("Unknown event type: " + type);
|
throw new ControlProtocolException("Unknown event type: " + type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import com.genymobile.scrcpy.device.Size;
|
||||||
import com.genymobile.scrcpy.util.Ln;
|
import com.genymobile.scrcpy.util.Ln;
|
||||||
import com.genymobile.scrcpy.util.LogUtils;
|
import com.genymobile.scrcpy.util.LogUtils;
|
||||||
import com.genymobile.scrcpy.video.SurfaceCapture;
|
import com.genymobile.scrcpy.video.SurfaceCapture;
|
||||||
|
import com.genymobile.scrcpy.video.SurfaceEncoder;
|
||||||
import com.genymobile.scrcpy.video.VirtualDisplayListener;
|
import com.genymobile.scrcpy.video.VirtualDisplayListener;
|
||||||
import com.genymobile.scrcpy.wrappers.ClipboardManager;
|
import com.genymobile.scrcpy.wrappers.ClipboardManager;
|
||||||
import com.genymobile.scrcpy.wrappers.InputManager;
|
import com.genymobile.scrcpy.wrappers.InputManager;
|
||||||
|
@ -99,6 +100,7 @@ public class Controller implements AsyncProcessor, VirtualDisplayListener {
|
||||||
|
|
||||||
// Used for resetting video encoding on RESET_VIDEO message
|
// Used for resetting video encoding on RESET_VIDEO message
|
||||||
private SurfaceCapture surfaceCapture;
|
private SurfaceCapture surfaceCapture;
|
||||||
|
private SurfaceEncoder surfaceEncoder;
|
||||||
|
|
||||||
public Controller(ControlChannel controlChannel, CleanUp cleanUp, Options options) {
|
public Controller(ControlChannel controlChannel, CleanUp cleanUp, Options options) {
|
||||||
this.displayId = options.getDisplayId();
|
this.displayId = options.getDisplayId();
|
||||||
|
@ -154,6 +156,10 @@ public class Controller implements AsyncProcessor, VirtualDisplayListener {
|
||||||
this.surfaceCapture = surfaceCapture;
|
this.surfaceCapture = surfaceCapture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSurfaceEncoder(SurfaceEncoder surfaceEncoder) {
|
||||||
|
this.surfaceEncoder = surfaceEncoder;
|
||||||
|
}
|
||||||
|
|
||||||
private UhidManager getUhidManager() {
|
private UhidManager getUhidManager() {
|
||||||
if (uhidManager == null) {
|
if (uhidManager == null) {
|
||||||
uhidManager = new UhidManager(sender);
|
uhidManager = new UhidManager(sender);
|
||||||
|
@ -307,6 +313,9 @@ public class Controller implements AsyncProcessor, VirtualDisplayListener {
|
||||||
case ControlMessage.TYPE_RESET_VIDEO:
|
case ControlMessage.TYPE_RESET_VIDEO:
|
||||||
resetVideo();
|
resetVideo();
|
||||||
break;
|
break;
|
||||||
|
case ControlMessage.TYPE_REQUEST_IDR:
|
||||||
|
requestIdr();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
@ -728,4 +737,11 @@ public class Controller implements AsyncProcessor, VirtualDisplayListener {
|
||||||
surfaceCapture.requestInvalidate();
|
surfaceCapture.requestInvalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void requestIdr() {
|
||||||
|
if (surfaceEncoder != null) {
|
||||||
|
Ln.i("Requesting IDR");
|
||||||
|
surfaceEncoder.requestIdr();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import android.os.Build;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
@ -52,6 +53,8 @@ public class SurfaceEncoder implements AsyncProcessor {
|
||||||
|
|
||||||
private final CaptureReset reset = new CaptureReset();
|
private final CaptureReset reset = new CaptureReset();
|
||||||
|
|
||||||
|
private final AtomicBoolean idrRequested = new AtomicBoolean();
|
||||||
|
|
||||||
public SurfaceEncoder(SurfaceCapture capture, Streamer streamer, Options options) {
|
public SurfaceEncoder(SurfaceCapture capture, Streamer streamer, Options options) {
|
||||||
this.capture = capture;
|
this.capture = capture;
|
||||||
this.streamer = streamer;
|
this.streamer = streamer;
|
||||||
|
@ -199,6 +202,13 @@ public class SurfaceEncoder implements AsyncProcessor {
|
||||||
|
|
||||||
boolean eos;
|
boolean eos;
|
||||||
do {
|
do {
|
||||||
|
if (idrRequested.get()) {
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putInt(MediaCodec.PARAMETER_KEY_REQUEST_SYNC_FRAME, 0);
|
||||||
|
codec.setParameters(bundle);
|
||||||
|
idrRequested.set(false);
|
||||||
|
}
|
||||||
|
|
||||||
int outputBufferId = codec.dequeueOutputBuffer(bufferInfo, -1);
|
int outputBufferId = codec.dequeueOutputBuffer(bufferInfo, -1);
|
||||||
try {
|
try {
|
||||||
eos = (bufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
|
eos = (bufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
|
||||||
|
@ -323,4 +333,8 @@ public class SurfaceEncoder implements AsyncProcessor {
|
||||||
thread.join();
|
thread.join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void requestIdr() {
|
||||||
|
idrRequested.set(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue