Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce latency by 1 frame #646

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,11 @@ _scrcpy_ window.

There is no visual feedback, a log is printed to the console.

The target directory can be changed on start:

```bash
scrcpy --push-target /sdcard/foo/bar/
```

### Read-only

Expand Down Expand Up @@ -289,6 +294,14 @@ latency), use:
scrcpy --render-expired-frames
```

### Custom window title

By default, the window title is the device model. It can be changed:

```bash
scrcpy --window-title 'My device'
```


### Forward audio

Expand Down
1 change: 0 additions & 1 deletion app/src/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#include "net.h"

#define DEVICE_NAME_FIELD_LENGTH 64
#define DEVICE_SDCARD_PATH "/sdcard/"

// name must be at least DEVICE_NAME_FIELD_LENGTH bytes
bool
Expand Down
21 changes: 14 additions & 7 deletions app/src/file_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@

#include "config.h"
#include "command.h"
#include "device.h"
#include "lock_util.h"
#include "log.h"

#define DEFAULT_PUSH_TARGET "/sdcard/"

static void
file_handler_request_destroy(struct file_handler_request *req) {
SDL_free(req->file);
}

bool
file_handler_init(struct file_handler *file_handler, const char *serial) {
file_handler_init(struct file_handler *file_handler, const char *serial,
const char *push_target) {

cbuf_init(&file_handler->queue);

Expand Down Expand Up @@ -46,6 +48,8 @@ file_handler_init(struct file_handler *file_handler, const char *serial) {
file_handler->stopped = false;
file_handler->current_process = PROCESS_NONE;

file_handler->push_target = push_target ? push_target : DEFAULT_PUSH_TARGET;

return true;
}

Expand All @@ -67,8 +71,8 @@ install_apk(const char *serial, const char *file) {
}

static process_t
push_file(const char *serial, const char *file) {
return adb_push(serial, file, DEVICE_SDCARD_PATH);
push_file(const char *serial, const char *file, const char *push_target) {
return adb_push(serial, file, push_target);
}

bool
Expand Down Expand Up @@ -124,7 +128,8 @@ run_file_handler(void *data) {
process = install_apk(file_handler->serial, req.file);
} else {
LOGI("Pushing %s...", req.file);
process = push_file(file_handler->serial, req.file);
process = push_file(file_handler->serial, req.file,
file_handler->push_target);
}
file_handler->current_process = process;
mutex_unlock(file_handler->mutex);
Expand All @@ -137,9 +142,11 @@ run_file_handler(void *data) {
}
} else {
if (process_check_success(process, "adb push")) {
LOGI("%s successfully pushed to /sdcard/", req.file);
LOGI("%s successfully pushed to %s", req.file,
file_handler->push_target);
} else {
LOGE("Failed to push %s to /sdcard/", req.file);
LOGE("Failed to push %s to %s", req.file,
file_handler->push_target);
}
}

Expand Down
4 changes: 3 additions & 1 deletion app/src/file_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ struct file_handler_request_queue CBUF(struct file_handler_request, 16);

struct file_handler {
char *serial;
const char *push_target;
SDL_Thread *thread;
SDL_mutex *mutex;
SDL_cond *event_cond;
Expand All @@ -32,7 +33,8 @@ struct file_handler {
};

bool
file_handler_init(struct file_handler *file_handler, const char *serial);
file_handler_init(struct file_handler *file_handler, const char *serial,
const char *push_target);

void
file_handler_destroy(struct file_handler *file_handler);
Expand Down
26 changes: 26 additions & 0 deletions app/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ struct args {
const char *serial;
const char *crop;
const char *record_filename;
const char *window_title;
const char *push_target;
enum recorder_format record_format;
bool fullscreen;
bool no_control;
Expand Down Expand Up @@ -75,6 +77,11 @@ static void usage(const char *arg0) {
" Set the TCP port the client listens on.\n"
" Default is %d.\n"
"\n"
" --push-target path\n"
" Set the target directory for pushing files to the device by\n"
" drag & drop. It is passed as-is to \"adb push\".\n"
" Default is \"/sdcard/\".\n"
"\n"
" -r, --record file.mp4\n"
" Record screen to file.\n"
" The format is determined by the -F/--record-format option if\n"
Expand Down Expand Up @@ -103,6 +110,9 @@ static void usage(const char *arg0) {
" -v, --version\n"
" Print the version of scrcpy.\n"
"\n"
" --window-title text\n"
" Set a custom window title.\n"
"\n"
"Shortcuts:\n"
"\n"
" Ctrl+f\n"
Expand Down Expand Up @@ -295,6 +305,8 @@ guess_record_format(const char *filename) {
}

#define OPT_RENDER_EXPIRED_FRAMES 1000
#define OPT_WINDOW_TITLE 1001
#define OPT_PUSH_TARGET 1002

static bool
parse_args(struct args *args, int argc, char *argv[]) {
Expand All @@ -308,6 +320,8 @@ parse_args(struct args *args, int argc, char *argv[]) {
{"no-control", no_argument, NULL, 'n'},
{"no-display", no_argument, NULL, 'N'},
{"port", required_argument, NULL, 'p'},
{"push-target", required_argument, NULL,
OPT_PUSH_TARGET},
{"record", required_argument, NULL, 'r'},
{"record-format", required_argument, NULL, 'f'},
{"render-expired-frames", no_argument, NULL,
Expand All @@ -316,6 +330,8 @@ parse_args(struct args *args, int argc, char *argv[]) {
{"show-touches", no_argument, NULL, 't'},
{"turn-screen-off", no_argument, NULL, 'S'},
{"version", no_argument, NULL, 'v'},
{"window-title", required_argument, NULL,
OPT_WINDOW_TITLE},
{NULL, 0, NULL, 0 },
};
int c;
Expand Down Expand Up @@ -378,6 +394,12 @@ parse_args(struct args *args, int argc, char *argv[]) {
case OPT_RENDER_EXPIRED_FRAMES:
args->render_expired_frames = true;
break;
case OPT_WINDOW_TITLE:
args->window_title = optarg;
break;
case OPT_PUSH_TARGET:
args->push_target = optarg;
break;
default:
// getopt prints the error message on stderr
return false;
Expand Down Expand Up @@ -434,6 +456,8 @@ main(int argc, char *argv[]) {
.serial = NULL,
.crop = NULL,
.record_filename = NULL,
.window_title = NULL,
.push_target = NULL,
.record_format = 0,
.help = false,
.version = false,
Expand Down Expand Up @@ -478,6 +502,8 @@ main(int argc, char *argv[]) {
.crop = args.crop,
.port = args.port,
.record_filename = args.record_filename,
.window_title = args.window_title,
.push_target = args.push_target,
.record_format = args.record_format,
.max_size = args.max_size,
.bit_rate = args.bit_rate,
Expand Down
10 changes: 10 additions & 0 deletions app/src/recorder.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,21 @@ recorder_rescale_packet(struct recorder *recorder, AVPacket *packet) {
bool
recorder_write(struct recorder *recorder, AVPacket *packet) {
if (!recorder->header_written) {
if (packet->pts != AV_NOPTS_VALUE) {
LOGE("The first packet is not a config packet");
return false;
}
bool ok = recorder_write_header(recorder, packet);
if (!ok) {
return false;
}
recorder->header_written = true;
return true;
}

if (packet->pts == AV_NOPTS_VALUE) {
// ignore config packets
return true;
}

recorder_rescale_packet(recorder, packet);
Expand Down
9 changes: 6 additions & 3 deletions app/src/scrcpy.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,6 @@ scrcpy(const struct scrcpy_options *options) {
.local_port = options->port,
.max_size = options->max_size,
.bit_rate = options->bit_rate,
.send_frame_meta = record,
.control = options->control,
};
if (!server_start(&server, options->serial, &params)) {
Expand Down Expand Up @@ -334,7 +333,8 @@ scrcpy(const struct scrcpy_options *options) {
video_buffer_initialized = true;

if (options->control) {
if (!file_handler_init(&file_handler, server.serial)) {
if (!file_handler_init(&file_handler, server.serial,
options->push_target)) {
goto end;
}
file_handler_initialized = true;
Expand Down Expand Up @@ -380,7 +380,10 @@ scrcpy(const struct scrcpy_options *options) {
controller_started = true;
}

if (!screen_init_rendering(&screen, device_name, frame_size,
const char *window_title =
options->window_title ? options->window_title : device_name;

if (!screen_init_rendering(&screen, window_title, frame_size,
options->always_on_top)) {
goto end;
}
Expand Down
2 changes: 2 additions & 0 deletions app/src/scrcpy.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ struct scrcpy_options {
const char *serial;
const char *crop;
const char *record_filename;
const char *window_title;
const char *push_target;
enum recorder_format record_format;
uint16_t port;
uint16_t max_size;
Expand Down
4 changes: 2 additions & 2 deletions app/src/screen.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ create_texture(SDL_Renderer *renderer, struct size frame_size) {
}

bool
screen_init_rendering(struct screen *screen, const char *device_name,
screen_init_rendering(struct screen *screen, const char *window_title,
struct size frame_size, bool always_on_top) {
screen->frame_size = frame_size;

Expand All @@ -152,7 +152,7 @@ screen_init_rendering(struct screen *screen, const char *device_name,
#endif
}

screen->window = SDL_CreateWindow(device_name, SDL_WINDOWPOS_UNDEFINED,
screen->window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
window_size.width, window_size.height,
window_flags);
Expand Down
2 changes: 1 addition & 1 deletion app/src/screen.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ screen_init(struct screen *screen);

// initialize screen, create window, renderer and texture (window is hidden)
bool
screen_init_rendering(struct screen *screen, const char *device_name,
screen_init_rendering(struct screen *screen, const char *window_title,
struct size frame_size, bool always_on_top);

// show the window
Expand Down
2 changes: 1 addition & 1 deletion app/src/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ execute_server(struct server *server, const struct server_params *params) {
bit_rate_string,
server->tunnel_forward ? "true" : "false",
params->crop ? params->crop : "-",
params->send_frame_meta ? "true" : "false",
"true", // always send frame meta (packet boundaries + timestamp)
params->control ? "true" : "false",
};
return adb_execute(server->serial, cmd, sizeof(cmd) / sizeof(cmd[0]));
Expand Down
1 change: 0 additions & 1 deletion app/src/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ struct server_params {
uint16_t local_port;
uint16_t max_size;
uint32_t bit_rate;
bool send_frame_meta;
bool control;
};

Expand Down
Loading