Use different sockets for video and control
The socket used the device-to-computer direction to stream the video and the computer-to-device direction to send control events. Some features, like copy-paste from device to computer, require to send non-video data from the device to the computer. To make them possible, use two sockets: - one for streaming the video from the device to the client; - one for control/events in both direction.
This commit is contained in:
@@ -296,15 +296,13 @@ scrcpy(const struct scrcpy_options *options) {
|
||||
goto finally_destroy_server;
|
||||
}
|
||||
|
||||
socket_t device_socket = server.device_socket;
|
||||
|
||||
char device_name[DEVICE_NAME_FIELD_LENGTH];
|
||||
struct size frame_size;
|
||||
|
||||
// screenrecord does not send frames when the screen content does not
|
||||
// change therefore, we transmit the screen size before the video stream,
|
||||
// to be able to init the window immediately
|
||||
if (!device_read_info(device_socket, device_name, &frame_size)) {
|
||||
if (!device_read_info(server.video_socket, device_name, &frame_size)) {
|
||||
server_stop(&server);
|
||||
ret = false;
|
||||
goto finally_destroy_server;
|
||||
@@ -343,7 +341,7 @@ scrcpy(const struct scrcpy_options *options) {
|
||||
|
||||
av_log_set_callback(av_log_callback);
|
||||
|
||||
stream_init(&stream, device_socket, dec, rec);
|
||||
stream_init(&stream, server.video_socket, dec, rec);
|
||||
|
||||
// now we consumed the header values, the socket receives the video stream
|
||||
// start the stream
|
||||
@@ -355,7 +353,7 @@ scrcpy(const struct scrcpy_options *options) {
|
||||
|
||||
if (display) {
|
||||
if (control) {
|
||||
if (!controller_init(&controller, device_socket)) {
|
||||
if (!controller_init(&controller, server.control_socket)) {
|
||||
ret = false;
|
||||
goto finally_stop_stream;
|
||||
}
|
||||
|
||||
@@ -222,8 +222,14 @@ server_start(struct server *server, const char *serial,
|
||||
bool
|
||||
server_connect_to(struct server *server) {
|
||||
if (!server->tunnel_forward) {
|
||||
server->device_socket = net_accept(server->server_socket);
|
||||
if (server->device_socket == INVALID_SOCKET) {
|
||||
server->video_socket = net_accept(server->server_socket);
|
||||
if (server->video_socket == INVALID_SOCKET) {
|
||||
return false;
|
||||
}
|
||||
|
||||
server->control_socket = net_accept(server->server_socket);
|
||||
if (server->control_socket == INVALID_SOCKET) {
|
||||
// the video_socket will be clean up on destroy
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -232,9 +238,16 @@ server_connect_to(struct server *server) {
|
||||
} else {
|
||||
uint32_t attempts = 100;
|
||||
uint32_t delay = 100; // ms
|
||||
server->device_socket = connect_to_server(server->local_port, attempts,
|
||||
delay);
|
||||
if (server->device_socket == INVALID_SOCKET) {
|
||||
server->video_socket =
|
||||
connect_to_server(server->local_port, attempts, delay);
|
||||
if (server->video_socket == INVALID_SOCKET) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// we know that the device is listening, we don't need several attempts
|
||||
server->control_socket =
|
||||
net_connect(IPV4_LOCALHOST, server->local_port);
|
||||
if (server->control_socket == INVALID_SOCKET) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -268,8 +281,11 @@ server_destroy(struct server *server) {
|
||||
if (server->server_socket != INVALID_SOCKET) {
|
||||
close_socket(&server->server_socket);
|
||||
}
|
||||
if (server->device_socket != INVALID_SOCKET) {
|
||||
close_socket(&server->device_socket);
|
||||
if (server->video_socket != INVALID_SOCKET) {
|
||||
close_socket(&server->video_socket);
|
||||
}
|
||||
if (server->control_socket != INVALID_SOCKET) {
|
||||
close_socket(&server->control_socket);
|
||||
}
|
||||
SDL_free(server->serial);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,8 @@ struct server {
|
||||
char *serial;
|
||||
process_t process;
|
||||
socket_t server_socket; // only used if !tunnel_forward
|
||||
socket_t device_socket;
|
||||
socket_t video_socket;
|
||||
socket_t control_socket;
|
||||
uint16_t local_port;
|
||||
bool tunnel_enabled;
|
||||
bool tunnel_forward; // use "adb forward" instead of "adb reverse"
|
||||
@@ -22,7 +23,8 @@ struct server {
|
||||
.serial = NULL, \
|
||||
.process = PROCESS_NONE, \
|
||||
.server_socket = INVALID_SOCKET, \
|
||||
.device_socket = INVALID_SOCKET, \
|
||||
.video_socket = INVALID_SOCKET, \
|
||||
.control_socket = INVALID_SOCKET, \
|
||||
.local_port = 0, \
|
||||
.tunnel_enabled = false, \
|
||||
.tunnel_forward = false, \
|
||||
|
||||
Reference in New Issue
Block a user