Skip to content

Commit

Permalink
Add shortcut to reset video capture/encoding
Browse files Browse the repository at this point in the history
Reset video capture/encoding on MOD+Shift+r.

Like on device rotation, this starts a new encoding session which
produces a video stream starting by a key frame.
  • Loading branch information
rom1v committed Oct 31, 2024
1 parent c70b4c4 commit 10632e6
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 2 deletions.
4 changes: 4 additions & 0 deletions app/scrcpy.1
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,10 @@ Pause or re-pause display
.B MOD+Shift+z
Unpause display

.TP
.B MOD+Shift+r
Reset video capture/encoding

.TP
.B MOD+g
Resize window to 1:1 (pixel\-perfect)
Expand Down
4 changes: 4 additions & 0 deletions app/src/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -1022,6 +1022,10 @@ static const struct sc_shortcut shortcuts[] = {
.shortcuts = { "MOD+Shift+z" },
.text = "Unpause display",
},
{
.shortcuts = { "MOD+Shift+r" },
.text = "Reset video capture/encoding",
},
{
.shortcuts = { "MOD+g" },
.text = "Resize window to 1:1 (pixel-perfect)",
Expand Down
4 changes: 4 additions & 0 deletions app/src/control_msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ sc_control_msg_serialize(const struct sc_control_msg *msg, uint8_t *buf) {
case SC_CONTROL_MSG_TYPE_COLLAPSE_PANELS:
case SC_CONTROL_MSG_TYPE_ROTATE_DEVICE:
case SC_CONTROL_MSG_TYPE_OPEN_HARD_KEYBOARD_SETTINGS:
case SC_CONTROL_MSG_TYPE_RESET_VIDEO:
// no additional data
return 1;
default:
Expand Down Expand Up @@ -304,6 +305,9 @@ sc_control_msg_log(const struct sc_control_msg *msg) {
case SC_CONTROL_MSG_TYPE_START_APP:
LOG_CMSG("start app \"%s\"", msg->start_app.name);
break;
case SC_CONTROL_MSG_TYPE_RESET_VIDEO:
LOG_CMSG("reset video");
break;
default:
LOG_CMSG("unknown type: %u", (unsigned) msg->type);
break;
Expand Down
1 change: 1 addition & 0 deletions app/src/control_msg.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ enum sc_control_msg_type {
SC_CONTROL_MSG_TYPE_UHID_DESTROY,
SC_CONTROL_MSG_TYPE_OPEN_HARD_KEYBOARD_SETTINGS,
SC_CONTROL_MSG_TYPE_START_APP,
SC_CONTROL_MSG_TYPE_RESET_VIDEO,
};

enum sc_copy_key {
Expand Down
20 changes: 18 additions & 2 deletions app/src/input_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,18 @@ open_hard_keyboard_settings(struct sc_input_manager *im) {
}
}

static void
reset_video(struct sc_input_manager *im) {
assert(im->controller);

struct sc_control_msg msg;
msg.type = SC_CONTROL_MSG_TYPE_RESET_VIDEO;

if (!sc_controller_push_msg(im->controller, &msg)) {
LOGW("Could not request reset video");
}
}

static void
apply_orientation_transform(struct sc_input_manager *im,
enum sc_orientation transform) {
Expand Down Expand Up @@ -521,8 +533,12 @@ sc_input_manager_process_key(struct sc_input_manager *im,
}
return;
case SDLK_r:
if (control && !shift && !repeat && down && !paused) {
rotate_device(im);
if (control && !repeat && down && !paused) {
if (shift) {
reset_video(im);
} else {
rotate_device(im);
}
}
return;
case SDLK_k:
Expand Down
16 changes: 16 additions & 0 deletions app/tests/test_control_msg_serialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,21 @@ static void test_serialize_open_hard_keyboard(void) {
assert(!memcmp(buf, expected, sizeof(expected)));
}

static void test_serialize_reset_video(void) {
struct sc_control_msg msg = {
.type = SC_CONTROL_MSG_TYPE_RESET_VIDEO,
};

uint8_t buf[SC_CONTROL_MSG_MAX_SIZE];
size_t size = sc_control_msg_serialize(&msg, buf);
assert(size == 1);

const uint8_t expected[] = {
SC_CONTROL_MSG_TYPE_RESET_VIDEO,
};
assert(!memcmp(buf, expected, sizeof(expected)));
}

int main(int argc, char *argv[]) {
(void) argc;
(void) argv;
Expand All @@ -429,5 +444,6 @@ int main(int argc, char *argv[]) {
test_serialize_uhid_input();
test_serialize_uhid_destroy();
test_serialize_open_hard_keyboard();
test_serialize_reset_video();
return 0;
}
4 changes: 4 additions & 0 deletions server/src/main/java/com/genymobile/scrcpy/Server.java
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,10 @@ private static void scrcpy(Options options) throws IOException, ConfigurationExc
SurfaceEncoder surfaceEncoder = new SurfaceEncoder(surfaceCapture, videoStreamer, options.getVideoBitRate(), options.getMaxFps(),
options.getVideoCodecOptions(), options.getVideoEncoder(), options.getDownsizeOnError());
asyncProcessors.add(surfaceEncoder);

if (controller != null) {
controller.setSurfaceEncoder(surfaceEncoder);
}
}

Completion completion = new Completion(asyncProcessors.size());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public final class ControlMessage {
public static final int TYPE_UHID_DESTROY = 14;
public static final int TYPE_OPEN_HARD_KEYBOARD_SETTINGS = 15;
public static final int TYPE_START_APP = 16;
public static final int TYPE_RESET_VIDEO = 17;

public static final long SEQUENCE_INVALID = 0;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public ControlMessage read() throws IOException {
case ControlMessage.TYPE_COLLAPSE_PANELS:
case ControlMessage.TYPE_ROTATE_DEVICE:
case ControlMessage.TYPE_OPEN_HARD_KEYBOARD_SETTINGS:
case ControlMessage.TYPE_RESET_VIDEO:
return ControlMessage.createEmpty(type);
case ControlMessage.TYPE_UHID_CREATE:
return parseUhidCreate();
Expand Down
18 changes: 18 additions & 0 deletions server/src/main/java/com/genymobile/scrcpy/control/Controller.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.genymobile.scrcpy.device.Position;
import com.genymobile.scrcpy.util.Ln;
import com.genymobile.scrcpy.util.LogUtils;
import com.genymobile.scrcpy.video.SurfaceEncoder;
import com.genymobile.scrcpy.video.VirtualDisplayListener;
import com.genymobile.scrcpy.wrappers.ClipboardManager;
import com.genymobile.scrcpy.wrappers.InputManager;
Expand Down Expand Up @@ -93,6 +94,9 @@ private DisplayData(int virtualDisplayId, PositionMapper positionMapper) {

private boolean keepDisplayPowerOff;

// Used for resetting video capture/encoding on RESET_VIDEO message
private SurfaceEncoder surfaceEncoder;

public Controller(int displayId, ControlChannel controlChannel, CleanUp cleanUp, boolean clipboardAutosync, boolean powerOn) {
this.displayId = displayId;
this.controlChannel = controlChannel;
Expand Down Expand Up @@ -143,6 +147,10 @@ public void onNewVirtualDisplay(int virtualDisplayId, PositionMapper positionMap
}
}

public void setSurfaceEncoder(SurfaceEncoder surfaceEncoder) {
this.surfaceEncoder = surfaceEncoder;
}

private UhidManager getUhidManager() {
if (uhidManager == null) {
uhidManager = new UhidManager(sender);
Expand Down Expand Up @@ -293,6 +301,9 @@ private boolean handleEvent() throws IOException {
case ControlMessage.TYPE_START_APP:
startAppAsync(msg.getText());
break;
case ControlMessage.TYPE_RESET_VIDEO:
resetVideo();
break;
default:
// do nothing
}
Expand Down Expand Up @@ -680,4 +691,11 @@ private void setDisplayPower(boolean on) {
}
}
}

private void resetVideo() {
if (surfaceEncoder != null) {
Ln.i("Video capture reset");
surfaceEncoder.requestReset();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -309,4 +309,11 @@ public void join() throws InterruptedException {
thread.join();
}
}

/**
* Reset the current encoding (as a consequence of an explicit request from the user).
*/
public void requestReset() {
reset.reset();
}
}

0 comments on commit 10632e6

Please sign in to comment.