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

Automatically retry with a lower definition on MediaCodec error #2947

Merged
merged 11 commits into from
Jan 21, 2022
3 changes: 3 additions & 0 deletions FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,9 @@ scrcpy -m 1024
scrcpy -m 800
```

Since scrcpy v1.22, scrcpy automatically tries again with a lower definition
before failing. This behavior can be disabled with `--no-downsize-on-error`.

You could also try another [encoder](README.md#encoder).


Expand Down
6 changes: 6 additions & 0 deletions app/scrcpy.1
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ By default, scrcpy automatically synchronizes the computer clipboard to the devi

This option disables this automatic synchronization.

.TP
.B \-\-no\-downsize\-on\-error
By default, on MediaCodec error, scrcpy automatically tries again with a lower definition.

This option disables this behavior.

.TP
.B \-n, \-\-no\-control
Disable device control (mirror the device in read\-only).
Expand Down
28 changes: 23 additions & 5 deletions app/src/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
#define OPT_NO_CLIPBOARD_AUTOSYNC 1032
#define OPT_TCPIP 1033
#define OPT_RAW_KEY_EVENTS 1034
#define OPT_NO_DOWNSIZE_ON_ERROR 1035

struct sc_option {
char shortopt;
Expand Down Expand Up @@ -236,6 +237,13 @@ static const struct sc_option options[] = {
"is preserved.\n"
"Default is 0 (unlimited).",
},
{
.longopt_id = OPT_NO_DOWNSIZE_ON_ERROR,
.longopt = "no-downsize-on-error",
.text = "By default, on MediaCodec error, scrcpy automatically tries "
"again with a lower definition.\n"
"This option disables this behavior.",
},
{
.longopt_id = OPT_NO_CLIPBOARD_AUTOSYNC,
.longopt = "no-clipboard-autosync",
Expand Down Expand Up @@ -1489,6 +1497,9 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
opts->tcpip = true;
opts->tcpip_dst = optarg;
break;
case OPT_NO_DOWNSIZE_ON_ERROR:
opts->downsize_on_error = false;
break;
case OPT_V4L2_SINK:
#ifdef HAVE_V4L2
opts->v4l2_device = optarg;
Expand Down Expand Up @@ -1534,11 +1545,18 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
return false;
}

if (opts->v4l2_device && opts->lock_video_orientation
== SC_LOCK_VIDEO_ORIENTATION_UNLOCKED) {
LOGI("Video orientation is locked for v4l2 sink. "
"See --lock-video-orientation.");
opts->lock_video_orientation = SC_LOCK_VIDEO_ORIENTATION_INITIAL;
if (opts->v4l2_device) {
if (opts->lock_video_orientation ==
SC_LOCK_VIDEO_ORIENTATION_UNLOCKED) {
LOGI("Video orientation is locked for v4l2 sink. "
"See --lock-video-orientation.");
opts->lock_video_orientation = SC_LOCK_VIDEO_ORIENTATION_INITIAL;
}

// V4L2 could not handle size change.
// Do not log because downsizing on error is the default behavior,
// not an explicit request from the user.
opts->downsize_on_error = false;
}

if (opts->v4l2_buffer && !opts->v4l2_device) {
Expand Down
1 change: 1 addition & 0 deletions app/src/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ const struct scrcpy_options scrcpy_options_default = {
.legacy_paste = false,
.power_off_on_close = false,
.clipboard_autosync = true,
.downsize_on_error = true,
.tcpip = false,
.tcpip_dst = NULL,
};
1 change: 1 addition & 0 deletions app/src/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ struct scrcpy_options {
bool legacy_paste;
bool power_off_on_close;
bool clipboard_autosync;
bool downsize_on_error;
bool tcpip;
const char *tcpip_dst;
};
Expand Down
1 change: 1 addition & 0 deletions app/src/scrcpy.c
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ scrcpy(struct scrcpy_options *options) {
.force_adb_forward = options->force_adb_forward,
.power_off_on_close = options->power_off_on_close,
.clipboard_autosync = options->clipboard_autosync,
.downsize_on_error = options->downsize_on_error,
.tcpip = options->tcpip,
.tcpip_dst = options->tcpip_dst,
};
Expand Down
62 changes: 34 additions & 28 deletions app/src/screen.c
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,12 @@ sc_screen_init(struct sc_screen *screen,
screen->mouse_captured = false;
screen->mouse_capture_key_pressed = 0;

screen->req.x = params->window_x;
screen->req.y = params->window_y;
screen->req.width = params->window_width;
screen->req.height = params->window_height;
screen->req.fullscreen = params->fullscreen;

static const struct sc_video_buffer_callbacks cbs = {
.on_new_frame = sc_video_buffer_on_new_frame,
};
Expand Down Expand Up @@ -397,9 +403,6 @@ sc_screen_init(struct sc_screen *screen,
get_rotated_size(screen->frame_size, screen->rotation);
screen->content_size = content_size;

struct sc_size window_size =
get_initial_optimal_size(content_size,params->window_width,
params->window_height);
uint32_t window_flags = SDL_WINDOW_HIDDEN
| SDL_WINDOW_RESIZABLE
| SDL_WINDOW_ALLOW_HIGHDPI;
Expand All @@ -410,13 +413,9 @@ sc_screen_init(struct sc_screen *screen,
window_flags |= SDL_WINDOW_BORDERLESS;
}

int x = params->window_x != SC_WINDOW_POSITION_UNDEFINED
? params->window_x : (int) SDL_WINDOWPOS_UNDEFINED;
int y = params->window_y != SC_WINDOW_POSITION_UNDEFINED
? params->window_y : (int) SDL_WINDOWPOS_UNDEFINED;
screen->window = SDL_CreateWindow(params->window_title, x, y,
window_size.width, window_size.height,
window_flags);
// The window will be positioned and sized on first video frame
screen->window =
SDL_CreateWindow(params->window_title, 0, 0, 0, 0, window_flags);
if (!screen->window) {
LOGC("Could not create window: %s", SDL_GetError());
goto error_destroy_fps_counter;
Expand Down Expand Up @@ -498,17 +497,6 @@ sc_screen_init(struct sc_screen *screen,

sc_input_manager_init(&screen->im, &im_params);

// Reset the window size to trigger a SIZE_CHANGED event, to workaround
// HiDPI issues with some SDL renderers when several displays having
// different HiDPI scaling are connected
SDL_SetWindowSize(screen->window, window_size.width, window_size.height);

sc_screen_update_content_rect(screen);

if (params->fullscreen) {
sc_screen_switch_fullscreen(screen);
}

#ifdef CONTINUOUS_RESIZING_WORKAROUND
SDL_AddEventWatch(event_watcher, screen);
#endif
Expand Down Expand Up @@ -545,7 +533,23 @@ sc_screen_init(struct sc_screen *screen,
}

static void
sc_screen_show_window(struct sc_screen *screen) {
sc_screen_show_initial_window(struct sc_screen *screen) {
int x = screen->req.x != SC_WINDOW_POSITION_UNDEFINED
? screen->req.x : (int) SDL_WINDOWPOS_CENTERED;
int y = screen->req.y != SC_WINDOW_POSITION_UNDEFINED
? screen->req.y : (int) SDL_WINDOWPOS_CENTERED;

struct sc_size window_size =
get_initial_optimal_size(screen->content_size, screen->req.width,
screen->req.height);

set_window_size(screen, window_size);
SDL_SetWindowPosition(screen->window, x, y);

if (screen->req.fullscreen) {
sc_screen_switch_fullscreen(screen);
}

SDL_ShowWindow(screen->window);
}

Expand Down Expand Up @@ -693,6 +697,12 @@ sc_screen_update_frame(struct sc_screen *screen) {
}
update_texture(screen, frame);

if (!screen->has_frame) {
screen->has_frame = true;
// this is the very first frame, show the window
sc_screen_show_initial_window(screen);
}

sc_screen_render(screen, false);
return true;
}
Expand Down Expand Up @@ -763,17 +773,13 @@ sc_screen_is_mouse_capture_key(SDL_Keycode key) {
bool
sc_screen_handle_event(struct sc_screen *screen, SDL_Event *event) {
switch (event->type) {
case EVENT_NEW_FRAME:
if (!screen->has_frame) {
screen->has_frame = true;
// this is the very first frame, show the window
sc_screen_show_window(screen);
}
case EVENT_NEW_FRAME: {
bool ok = sc_screen_update_frame(screen);
if (!ok) {
LOGW("Frame update failed\n");
}
return true;
}
case SDL_WINDOWEVENT:
if (!screen->has_frame) {
// Do nothing
Expand Down
17 changes: 13 additions & 4 deletions app/src/screen.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ struct sc_screen {
struct sc_video_buffer vb;
struct fps_counter fps_counter;

// The initial requested window properties
struct {
int16_t x;
int16_t y;
uint16_t width;
uint16_t height;
bool fullscreen;
} req;

SDL_Window *window;
SDL_Renderer *renderer;
SDL_Texture *texture;
Expand Down Expand Up @@ -74,10 +83,10 @@ struct sc_screen_params {
struct sc_size frame_size;
bool always_on_top;

int16_t window_x;
int16_t window_y;
uint16_t window_width; // accepts SC_WINDOW_POSITION_UNDEFINED
uint16_t window_height; // accepts SC_WINDOW_POSITION_UNDEFINED
int16_t window_x; // accepts SC_WINDOW_POSITION_UNDEFINED
int16_t window_y; // accepts SC_WINDOW_POSITION_UNDEFINED
uint16_t window_width;
uint16_t window_height;

bool window_borderless;

Expand Down
4 changes: 4 additions & 0 deletions app/src/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,10 @@ execute_server(struct sc_server *server,
// By default, clipboard_autosync is true
ADD_PARAM("clipboard_autosync=false");
}
if (!params->downsize_on_error) {
// By default, downsize_on_error is true
ADD_PARAM("downsize_on_error=false");
}

#undef ADD_PARAM
#undef STRBOOL
Expand Down
1 change: 1 addition & 0 deletions app/src/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ struct sc_server_params {
bool force_adb_forward;
bool power_off_on_close;
bool clipboard_autosync;
bool downsize_on_error;
bool tcpip;
const char *tcpip_dst;
};
Expand Down
17 changes: 16 additions & 1 deletion server/src/main/java/com/genymobile/scrcpy/Device.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ public interface ClipboardListener {
void onClipboardTextChanged(String text);
}

private final Size deviceSize;
private final Rect crop;
private int maxSize;
private final int lockVideoOrientation;

private ScreenInfo screenInfo;
private RotationListener rotationListener;
private ClipboardListener clipboardListener;
Expand Down Expand Up @@ -69,7 +74,12 @@ public Device(Options options) {

int displayInfoFlags = displayInfo.getFlags();

screenInfo = ScreenInfo.computeScreenInfo(displayInfo, options.getCrop(), options.getMaxSize(), options.getLockVideoOrientation());
deviceSize = displayInfo.getSize();
crop = options.getCrop();
maxSize = options.getMaxSize();
lockVideoOrientation = options.getLockVideoOrientation();

screenInfo = ScreenInfo.computeScreenInfo(displayInfo.getRotation(), deviceSize, crop, maxSize, lockVideoOrientation);
layerStack = displayInfo.getLayerStack();

SERVICE_MANAGER.getWindowManager().registerRotationWatcher(new IRotationWatcher.Stub() {
Expand Down Expand Up @@ -123,6 +133,11 @@ public void dispatchPrimaryClipChanged() {
}
}

public synchronized void setMaxSize(int newMaxSize) {
maxSize = newMaxSize;
screenInfo = ScreenInfo.computeScreenInfo(screenInfo.getReverseVideoRotation(), deviceSize, crop, newMaxSize, lockVideoOrientation);
}

public synchronized ScreenInfo getScreenInfo() {
return screenInfo;
}
Expand Down
9 changes: 9 additions & 0 deletions server/src/main/java/com/genymobile/scrcpy/Options.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class Options {
private String encoderName;
private boolean powerOffScreenOnClose;
private boolean clipboardAutosync = true;
private boolean downsizeOnError = true;

public Ln.Level getLogLevel() {
return logLevel;
Expand Down Expand Up @@ -149,4 +150,12 @@ public boolean getClipboardAutosync() {
public void setClipboardAutosync(boolean clipboardAutosync) {
this.clipboardAutosync = clipboardAutosync;
}

public boolean getDownsizeOnError() {
return downsizeOnError;
}

public void setDownsizeOnError(boolean downsizeOnError) {
this.downsizeOnError = downsizeOnError;
}
}
Loading