Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3638e8ea17 | ||
|
|
88f4a035ab | ||
|
|
92e0898661 | ||
|
|
3e65b587ae | ||
|
|
06a3f13bd0 | ||
|
|
79309f8fd5 | ||
|
|
6145ad2f12 | ||
|
|
1d7c74d0f3 | ||
|
|
e4ac021da4 |
@@ -10,13 +10,10 @@ _scrcpy() {
|
|||||||
--audio-source=
|
--audio-source=
|
||||||
--audio-output-buffer=
|
--audio-output-buffer=
|
||||||
-b --video-bit-rate=
|
-b --video-bit-rate=
|
||||||
--camera-id=
|
|
||||||
--camera-facing=
|
|
||||||
--camera-size=
|
|
||||||
--crop=
|
--crop=
|
||||||
-d --select-usb
|
-d --select-usb
|
||||||
--disable-screensaver
|
--disable-screensaver
|
||||||
--display-id=
|
--display=
|
||||||
--display-buffer=
|
--display-buffer=
|
||||||
-e --select-tcpip
|
-e --select-tcpip
|
||||||
-f --fullscreen
|
-f --fullscreen
|
||||||
@@ -77,7 +74,6 @@ _scrcpy() {
|
|||||||
--video-codec=
|
--video-codec=
|
||||||
--video-codec-options=
|
--video-codec-options=
|
||||||
--video-encoder=
|
--video-encoder=
|
||||||
--video-source=
|
|
||||||
-w --stay-awake
|
-w --stay-awake
|
||||||
--window-borderless
|
--window-borderless
|
||||||
--window-title=
|
--window-title=
|
||||||
@@ -97,18 +93,10 @@ _scrcpy() {
|
|||||||
COMPREPLY=($(compgen -W 'opus aac raw' -- "$cur"))
|
COMPREPLY=($(compgen -W 'opus aac raw' -- "$cur"))
|
||||||
return
|
return
|
||||||
;;
|
;;
|
||||||
--video-source)
|
|
||||||
COMPREPLY=($(compgen -W 'display camera' -- "$cur"))
|
|
||||||
return
|
|
||||||
;;
|
|
||||||
--audio-source)
|
--audio-source)
|
||||||
COMPREPLY=($(compgen -W 'output mic' -- "$cur"))
|
COMPREPLY=($(compgen -W 'output mic' -- "$cur"))
|
||||||
return
|
return
|
||||||
;;
|
;;
|
||||||
--camera-facing)
|
|
||||||
COMPREPLY=($(compgen -W 'front back external' -- "$cur"))
|
|
||||||
return
|
|
||||||
;;
|
|
||||||
--lock-video-orientation)
|
--lock-video-orientation)
|
||||||
COMPREPLY=($(compgen -W 'unlocked initial 0 1 2 3' -- "$cur"))
|
COMPREPLY=($(compgen -W 'unlocked initial 0 1 2 3' -- "$cur"))
|
||||||
return
|
return
|
||||||
@@ -153,10 +141,8 @@ _scrcpy() {
|
|||||||
|--audio-codec-options \
|
|--audio-codec-options \
|
||||||
|--audio-encoder \
|
|--audio-encoder \
|
||||||
|--audio-output-buffer \
|
|--audio-output-buffer \
|
||||||
|--camera-id \
|
|
||||||
|--camera-size \
|
|
||||||
|--crop \
|
|--crop \
|
||||||
|--display-id \
|
|--display \
|
||||||
|--display-buffer \
|
|--display-buffer \
|
||||||
|--max-fps \
|
|--max-fps \
|
||||||
|-m|--max-size \
|
|-m|--max-size \
|
||||||
|
|||||||
@@ -17,13 +17,10 @@ arguments=(
|
|||||||
'--audio-source=[Select the audio source]:source:(output mic)'
|
'--audio-source=[Select the audio source]:source:(output mic)'
|
||||||
'--audio-output-buffer=[Configure the size of the SDL audio output buffer (in milliseconds)]'
|
'--audio-output-buffer=[Configure the size of the SDL audio output buffer (in milliseconds)]'
|
||||||
{-b,--video-bit-rate=}'[Encode the video at the given bit-rate]'
|
{-b,--video-bit-rate=}'[Encode the video at the given bit-rate]'
|
||||||
'--camera-id=[Specify the camera id to mirror]'
|
|
||||||
'--camera-facing=[Select the device camera by its facing direction]:facing:(front back external)'
|
|
||||||
'--camera-size=[Specify an explicit camera capture size]'
|
|
||||||
'--crop=[\[width\:height\:x\:y\] Crop the device screen on the server]'
|
'--crop=[\[width\:height\:x\:y\] Crop the device screen on the server]'
|
||||||
{-d,--select-usb}'[Use USB device]'
|
{-d,--select-usb}'[Use USB device]'
|
||||||
'--disable-screensaver[Disable screensaver while scrcpy is running]'
|
'--disable-screensaver[Disable screensaver while scrcpy is running]'
|
||||||
'--display-id=[Specify the display id to mirror]'
|
'--display=[Specify the display id to mirror]'
|
||||||
'--display-buffer=[Add a buffering delay \(in milliseconds\) before displaying]'
|
'--display-buffer=[Add a buffering delay \(in milliseconds\) before displaying]'
|
||||||
{-e,--select-tcpip}'[Use TCP/IP device]'
|
{-e,--select-tcpip}'[Use TCP/IP device]'
|
||||||
{-f,--fullscreen}'[Start in fullscreen]'
|
{-f,--fullscreen}'[Start in fullscreen]'
|
||||||
@@ -81,7 +78,6 @@ arguments=(
|
|||||||
'--video-codec=[Select the video codec]:codec:(h264 h265 av1)'
|
'--video-codec=[Select the video codec]:codec:(h264 h265 av1)'
|
||||||
'--video-codec-options=[Set a list of comma-separated key\:type=value options for the device video encoder]'
|
'--video-codec-options=[Set a list of comma-separated key\:type=value options for the device video encoder]'
|
||||||
'--video-encoder=[Use a specific MediaCodec video encoder]'
|
'--video-encoder=[Use a specific MediaCodec video encoder]'
|
||||||
'--video-source=[Select the video source]:source:(display camera)'
|
|
||||||
{-w,--stay-awake}'[Keep the device on while scrcpy is running, when the device is plugged in]'
|
{-w,--stay-awake}'[Keep the device on while scrcpy is running, when the device is plugged in]'
|
||||||
'--window-borderless[Disable window decorations \(display borderless window\)]'
|
'--window-borderless[Disable window decorations \(display borderless window\)]'
|
||||||
'--window-title=[Set a custom window title]'
|
'--window-title=[Set a custom window title]'
|
||||||
|
|||||||
24
app/scrcpy.1
24
app/scrcpy.1
@@ -75,22 +75,6 @@ Encode the video at the given bit rate, expressed in bits/s. Unit suffixes are s
|
|||||||
|
|
||||||
Default is 8M (8000000).
|
Default is 8M (8000000).
|
||||||
|
|
||||||
.TP
|
|
||||||
.BI "\-\-camera\-id " id
|
|
||||||
Specify the device camera id to mirror.
|
|
||||||
|
|
||||||
The available camera ids can be listed by \-\-list\-cameras.
|
|
||||||
|
|
||||||
.TP
|
|
||||||
.BI "\-\-camera\-facing " facing
|
|
||||||
Select the device camera by its facing direction.
|
|
||||||
|
|
||||||
Possible values are "front", "back" and "external".
|
|
||||||
|
|
||||||
.TP
|
|
||||||
.BI "\-\-camera\-size " width\fRx\fIheight
|
|
||||||
Specify an explicit camera capture size.
|
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.BI "\-\-crop " width\fR:\fIheight\fR:\fIx\fR:\fIy
|
.BI "\-\-crop " width\fR:\fIheight\fR:\fIx\fR:\fIy
|
||||||
Crop the device screen on the server.
|
Crop the device screen on the server.
|
||||||
@@ -110,7 +94,7 @@ Also see \fB\-e\fR (\fB\-\-select\-tcpip\fR).
|
|||||||
Disable screensaver while scrcpy is running.
|
Disable screensaver while scrcpy is running.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.BI "\-\-display\-id " id
|
.BI "\-\-display " id
|
||||||
Specify the device display id to mirror.
|
Specify the device display id to mirror.
|
||||||
|
|
||||||
The available display ids can be listed by \-\-list\-displays.
|
The available display ids can be listed by \-\-list\-displays.
|
||||||
@@ -448,12 +432,6 @@ Use a specific MediaCodec video encoder (depending on the codec provided by \fB\
|
|||||||
|
|
||||||
The available encoders can be listed by \-\-list\-encoders.
|
The available encoders can be listed by \-\-list\-encoders.
|
||||||
|
|
||||||
.TP
|
|
||||||
.BI "\-\-video\-source " source
|
|
||||||
Select the video source (display or camera).
|
|
||||||
|
|
||||||
Default is display.
|
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B \-w, \-\-stay-awake
|
.B \-w, \-\-stay-awake
|
||||||
Keep the device on while scrcpy is running, when the device is plugged in.
|
Keep the device on while scrcpy is running, when the device is plugged in.
|
||||||
|
|||||||
@@ -218,16 +218,8 @@ sc_adb_forward(struct sc_intr *intr, const char *serial, uint16_t local_port,
|
|||||||
const char *device_socket_name, unsigned flags) {
|
const char *device_socket_name, unsigned flags) {
|
||||||
char local[4 + 5 + 1]; // tcp:PORT
|
char local[4 + 5 + 1]; // tcp:PORT
|
||||||
char remote[108 + 14 + 1]; // localabstract:NAME
|
char remote[108 + 14 + 1]; // localabstract:NAME
|
||||||
|
sprintf(local, "tcp:%" PRIu16, local_port);
|
||||||
int r = snprintf(local, sizeof(local), "tcp:%" PRIu16, local_port);
|
snprintf(remote, sizeof(remote), "localabstract:%s", device_socket_name);
|
||||||
assert(r >= 0 && (size_t) r < sizeof(local));
|
|
||||||
|
|
||||||
r = snprintf(remote, sizeof(remote), "localabstract:%s",
|
|
||||||
device_socket_name);
|
|
||||||
if (r < 0 || (size_t) r >= sizeof(remote)) {
|
|
||||||
LOGE("Could not write socket name");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(serial);
|
assert(serial);
|
||||||
const char *const argv[] =
|
const char *const argv[] =
|
||||||
@@ -241,9 +233,7 @@ bool
|
|||||||
sc_adb_forward_remove(struct sc_intr *intr, const char *serial,
|
sc_adb_forward_remove(struct sc_intr *intr, const char *serial,
|
||||||
uint16_t local_port, unsigned flags) {
|
uint16_t local_port, unsigned flags) {
|
||||||
char local[4 + 5 + 1]; // tcp:PORT
|
char local[4 + 5 + 1]; // tcp:PORT
|
||||||
int r = snprintf(local, sizeof(local), "tcp:%" PRIu16, local_port);
|
sprintf(local, "tcp:%" PRIu16, local_port);
|
||||||
assert(r >= 0 && (size_t) r < sizeof(local));
|
|
||||||
(void) r;
|
|
||||||
|
|
||||||
assert(serial);
|
assert(serial);
|
||||||
const char *const argv[] =
|
const char *const argv[] =
|
||||||
@@ -259,16 +249,8 @@ sc_adb_reverse(struct sc_intr *intr, const char *serial,
|
|||||||
unsigned flags) {
|
unsigned flags) {
|
||||||
char local[4 + 5 + 1]; // tcp:PORT
|
char local[4 + 5 + 1]; // tcp:PORT
|
||||||
char remote[108 + 14 + 1]; // localabstract:NAME
|
char remote[108 + 14 + 1]; // localabstract:NAME
|
||||||
int r = snprintf(local, sizeof(local), "tcp:%" PRIu16, local_port);
|
sprintf(local, "tcp:%" PRIu16, local_port);
|
||||||
assert(r >= 0 && (size_t) r < sizeof(local));
|
snprintf(remote, sizeof(remote), "localabstract:%s", device_socket_name);
|
||||||
|
|
||||||
r = snprintf(remote, sizeof(remote), "localabstract:%s",
|
|
||||||
device_socket_name);
|
|
||||||
if (r < 0 || (size_t) r >= sizeof(remote)) {
|
|
||||||
LOGE("Could not write socket name");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(serial);
|
assert(serial);
|
||||||
const char *const argv[] =
|
const char *const argv[] =
|
||||||
SC_ADB_COMMAND("-s", serial, "reverse", remote, local);
|
SC_ADB_COMMAND("-s", serial, "reverse", remote, local);
|
||||||
@@ -281,12 +263,7 @@ bool
|
|||||||
sc_adb_reverse_remove(struct sc_intr *intr, const char *serial,
|
sc_adb_reverse_remove(struct sc_intr *intr, const char *serial,
|
||||||
const char *device_socket_name, unsigned flags) {
|
const char *device_socket_name, unsigned flags) {
|
||||||
char remote[108 + 14 + 1]; // localabstract:NAME
|
char remote[108 + 14 + 1]; // localabstract:NAME
|
||||||
int r = snprintf(remote, sizeof(remote), "localabstract:%s",
|
snprintf(remote, sizeof(remote), "localabstract:%s", device_socket_name);
|
||||||
device_socket_name);
|
|
||||||
if (r < 0 || (size_t) r >= sizeof(remote)) {
|
|
||||||
LOGE("Device socket name too long");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(serial);
|
assert(serial);
|
||||||
const char *const argv[] =
|
const char *const argv[] =
|
||||||
@@ -356,9 +333,7 @@ bool
|
|||||||
sc_adb_tcpip(struct sc_intr *intr, const char *serial, uint16_t port,
|
sc_adb_tcpip(struct sc_intr *intr, const char *serial, uint16_t port,
|
||||||
unsigned flags) {
|
unsigned flags) {
|
||||||
char port_string[5 + 1];
|
char port_string[5 + 1];
|
||||||
int r = snprintf(port_string, sizeof(port_string), "%" PRIu16, port);
|
sprintf(port_string, "%" PRIu16, port);
|
||||||
assert(r >= 0 && (size_t) r < sizeof(port_string));
|
|
||||||
(void) r;
|
|
||||||
|
|
||||||
assert(serial);
|
assert(serial);
|
||||||
const char *const argv[] =
|
const char *const argv[] =
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ enum {
|
|||||||
OPT_WINDOW_BORDERLESS,
|
OPT_WINDOW_BORDERLESS,
|
||||||
OPT_MAX_FPS,
|
OPT_MAX_FPS,
|
||||||
OPT_LOCK_VIDEO_ORIENTATION,
|
OPT_LOCK_VIDEO_ORIENTATION,
|
||||||
OPT_DISPLAY,
|
|
||||||
OPT_DISPLAY_ID,
|
OPT_DISPLAY_ID,
|
||||||
OPT_ROTATION,
|
OPT_ROTATION,
|
||||||
OPT_RENDER_DRIVER,
|
OPT_RENDER_DRIVER,
|
||||||
@@ -86,7 +85,6 @@ enum {
|
|||||||
OPT_LIST_CAMERA_SIZES,
|
OPT_LIST_CAMERA_SIZES,
|
||||||
OPT_CAMERA_ID,
|
OPT_CAMERA_ID,
|
||||||
OPT_CAMERA_SIZE,
|
OPT_CAMERA_SIZE,
|
||||||
OPT_CAMERA_FACING,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sc_option {
|
struct sc_option {
|
||||||
@@ -205,18 +203,13 @@ static const struct sc_option options[] = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
.longopt_id = OPT_CAMERA_ID,
|
.longopt_id = OPT_CAMERA_ID,
|
||||||
.longopt = "camera-id",
|
.longopt = "camera",
|
||||||
.argdesc = "id",
|
.argdesc = "id",
|
||||||
.text = "Specify the device camera id to mirror.\n"
|
.text = "Specify the device camera id to mirror when using "
|
||||||
|
"--video-source=camera.\n"
|
||||||
"The available camera ids can be listed by:\n"
|
"The available camera ids can be listed by:\n"
|
||||||
" scrcpy --list-cameras",
|
" scrcpy --list-cameras\n"
|
||||||
},
|
"Default is \"auto\" (the first one)",
|
||||||
{
|
|
||||||
.longopt_id = OPT_CAMERA_FACING,
|
|
||||||
.longopt = "camera-facing",
|
|
||||||
.argdesc = "facing",
|
|
||||||
.text = "Select the device camera by its facing direction.\n"
|
|
||||||
"Possible values are \"front\", \"back\" and \"external\".",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.longopt_id = OPT_CAMERA_SIZE,
|
.longopt_id = OPT_CAMERA_SIZE,
|
||||||
@@ -259,15 +252,9 @@ static const struct sc_option options[] = {
|
|||||||
.longopt = "disable-screensaver",
|
.longopt = "disable-screensaver",
|
||||||
.text = "Disable screensaver while scrcpy is running.",
|
.text = "Disable screensaver while scrcpy is running.",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
// deprecated
|
|
||||||
.longopt_id = OPT_DISPLAY,
|
|
||||||
.longopt = "display",
|
|
||||||
.argdesc = "id",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
.longopt_id = OPT_DISPLAY_ID,
|
.longopt_id = OPT_DISPLAY_ID,
|
||||||
.longopt = "display-id",
|
.longopt = "display",
|
||||||
.argdesc = "id",
|
.argdesc = "id",
|
||||||
.text = "Specify the device display id to mirror.\n"
|
.text = "Specify the device display id to mirror.\n"
|
||||||
"The available display ids can be listed by:\n"
|
"The available display ids can be listed by:\n"
|
||||||
@@ -1707,34 +1694,6 @@ parse_audio_source(const char *optarg, enum sc_audio_source *source) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
parse_camera_facing(const char *optarg, enum sc_camera_facing *facing) {
|
|
||||||
if (!strcmp(optarg, "front")) {
|
|
||||||
*facing = SC_CAMERA_FACING_FRONT;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strcmp(optarg, "back")) {
|
|
||||||
*facing = SC_CAMERA_FACING_BACK;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strcmp(optarg, "external")) {
|
|
||||||
*facing = SC_CAMERA_FACING_EXTERNAL;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*optarg == '\0') {
|
|
||||||
// Empty string is a valid value (equivalent to not passing the option)
|
|
||||||
*facing = SC_CAMERA_FACING_ANY;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOGE("Unsupported camera facing: %s (expected front, back or external)",
|
|
||||||
optarg);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
parse_time_limit(const char *s, sc_tick *tick) {
|
parse_time_limit(const char *s, sc_tick *tick) {
|
||||||
long value;
|
long value;
|
||||||
@@ -1797,9 +1756,6 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
|
|||||||
case OPT_CROP:
|
case OPT_CROP:
|
||||||
opts->crop = optarg;
|
opts->crop = optarg;
|
||||||
break;
|
break;
|
||||||
case OPT_DISPLAY:
|
|
||||||
LOGW("--display is deprecated, use --display-id instead.");
|
|
||||||
// fall through
|
|
||||||
case OPT_DISPLAY_ID:
|
case OPT_DISPLAY_ID:
|
||||||
if (!parse_display_id(optarg, &opts->display_id)) {
|
if (!parse_display_id(optarg, &opts->display_id)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -2135,11 +2091,6 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
|
|||||||
case OPT_CAMERA_SIZE:
|
case OPT_CAMERA_SIZE:
|
||||||
opts->camera_size = optarg;
|
opts->camera_size = optarg;
|
||||||
break;
|
break;
|
||||||
case OPT_CAMERA_FACING:
|
|
||||||
if (!parse_camera_facing(optarg, &opts->camera_facing)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
// getopt prints the error message on stderr
|
// getopt prints the error message on stderr
|
||||||
return false;
|
return false;
|
||||||
@@ -2240,6 +2191,12 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!opts->camera_id) {
|
||||||
|
LOGE("Camera id must be specified by --camera=ID "
|
||||||
|
"(list the available ids with --list-cameras)");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!opts->camera_size) {
|
if (!opts->camera_size) {
|
||||||
LOGE("Camera size must be specified by --camera-size=WIDTHxHEIGHT");
|
LOGE("Camera size must be specified by --camera-size=WIDTHxHEIGHT");
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ const struct scrcpy_options scrcpy_options_default = {
|
|||||||
.record_format = SC_RECORD_FORMAT_AUTO,
|
.record_format = SC_RECORD_FORMAT_AUTO,
|
||||||
.keyboard_input_mode = SC_KEYBOARD_INPUT_MODE_INJECT,
|
.keyboard_input_mode = SC_KEYBOARD_INPUT_MODE_INJECT,
|
||||||
.mouse_input_mode = SC_MOUSE_INPUT_MODE_INJECT,
|
.mouse_input_mode = SC_MOUSE_INPUT_MODE_INJECT,
|
||||||
.camera_facing = SC_CAMERA_FACING_ANY,
|
|
||||||
.port_range = {
|
.port_range = {
|
||||||
.first = DEFAULT_LOCAL_PORT_RANGE_FIRST,
|
.first = DEFAULT_LOCAL_PORT_RANGE_FIRST,
|
||||||
.last = DEFAULT_LOCAL_PORT_RANGE_LAST,
|
.last = DEFAULT_LOCAL_PORT_RANGE_LAST,
|
||||||
|
|||||||
@@ -55,13 +55,6 @@ enum sc_audio_source {
|
|||||||
SC_AUDIO_SOURCE_MIC,
|
SC_AUDIO_SOURCE_MIC,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum sc_camera_facing {
|
|
||||||
SC_CAMERA_FACING_ANY,
|
|
||||||
SC_CAMERA_FACING_FRONT,
|
|
||||||
SC_CAMERA_FACING_BACK,
|
|
||||||
SC_CAMERA_FACING_EXTERNAL,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum sc_lock_video_orientation {
|
enum sc_lock_video_orientation {
|
||||||
SC_LOCK_VIDEO_ORIENTATION_UNLOCKED = -1,
|
SC_LOCK_VIDEO_ORIENTATION_UNLOCKED = -1,
|
||||||
// lock the current orientation when scrcpy starts
|
// lock the current orientation when scrcpy starts
|
||||||
@@ -140,7 +133,6 @@ struct scrcpy_options {
|
|||||||
enum sc_record_format record_format;
|
enum sc_record_format record_format;
|
||||||
enum sc_keyboard_input_mode keyboard_input_mode;
|
enum sc_keyboard_input_mode keyboard_input_mode;
|
||||||
enum sc_mouse_input_mode mouse_input_mode;
|
enum sc_mouse_input_mode mouse_input_mode;
|
||||||
enum sc_camera_facing camera_facing;
|
|
||||||
struct sc_port_range port_range;
|
struct sc_port_range port_range;
|
||||||
uint32_t tunnel_host;
|
uint32_t tunnel_host;
|
||||||
uint16_t tunnel_port;
|
uint16_t tunnel_port;
|
||||||
|
|||||||
@@ -353,7 +353,6 @@ scrcpy(struct scrcpy_options *options) {
|
|||||||
.audio_codec = options->audio_codec,
|
.audio_codec = options->audio_codec,
|
||||||
.video_source = options->video_source,
|
.video_source = options->video_source,
|
||||||
.audio_source = options->audio_source,
|
.audio_source = options->audio_source,
|
||||||
.camera_facing = options->camera_facing,
|
|
||||||
.crop = options->crop,
|
.crop = options->crop,
|
||||||
.port_range = options->port_range,
|
.port_range = options->port_range,
|
||||||
.tunnel_host = options->tunnel_host,
|
.tunnel_host = options->tunnel_host,
|
||||||
|
|||||||
@@ -183,20 +183,6 @@ sc_server_get_codec_name(enum sc_codec codec) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
|
||||||
sc_server_get_camera_facing_name(enum sc_camera_facing camera_facing) {
|
|
||||||
switch (camera_facing) {
|
|
||||||
case SC_CAMERA_FACING_FRONT:
|
|
||||||
return "front";
|
|
||||||
case SC_CAMERA_FACING_BACK:
|
|
||||||
return "back";
|
|
||||||
case SC_CAMERA_FACING_EXTERNAL:
|
|
||||||
return "external";
|
|
||||||
default:
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static sc_pid
|
static sc_pid
|
||||||
execute_server(struct sc_server *server,
|
execute_server(struct sc_server *server,
|
||||||
const struct sc_server_params *params) {
|
const struct sc_server_params *params) {
|
||||||
@@ -299,10 +285,6 @@ execute_server(struct sc_server *server,
|
|||||||
if (params->camera_size) {
|
if (params->camera_size) {
|
||||||
ADD_PARAM("camera_size=%s", params->camera_size);
|
ADD_PARAM("camera_size=%s", params->camera_size);
|
||||||
}
|
}
|
||||||
if (params->camera_facing != SC_CAMERA_FACING_ANY) {
|
|
||||||
ADD_PARAM("camera_facing=%s",
|
|
||||||
sc_server_get_camera_facing_name(params->camera_facing));
|
|
||||||
}
|
|
||||||
if (params->show_touches) {
|
if (params->show_touches) {
|
||||||
ADD_PARAM("show_touches=true");
|
ADD_PARAM("show_touches=true");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ struct sc_server_params {
|
|||||||
enum sc_codec audio_codec;
|
enum sc_codec audio_codec;
|
||||||
enum sc_video_source video_source;
|
enum sc_video_source video_source;
|
||||||
enum sc_audio_source audio_source;
|
enum sc_audio_source audio_source;
|
||||||
enum sc_camera_facing camera_facing;
|
|
||||||
const char *crop;
|
const char *crop;
|
||||||
const char *video_codec_options;
|
const char *video_codec_options;
|
||||||
const char *audio_codec_options;
|
const char *audio_codec_options;
|
||||||
|
|||||||
@@ -27,8 +27,7 @@
|
|||||||
// keyboard support, though OS could support more keys via modifying the report
|
// keyboard support, though OS could support more keys via modifying the report
|
||||||
// desc. 6 should be enough for scrcpy.
|
// desc. 6 should be enough for scrcpy.
|
||||||
#define HID_KEYBOARD_MAX_KEYS 6
|
#define HID_KEYBOARD_MAX_KEYS 6
|
||||||
#define HID_KEYBOARD_EVENT_SIZE \
|
#define HID_KEYBOARD_EVENT_SIZE (2 + HID_KEYBOARD_MAX_KEYS)
|
||||||
(HID_KEYBOARD_INDEX_KEYS + HID_KEYBOARD_MAX_KEYS)
|
|
||||||
|
|
||||||
#define HID_RESERVED 0x00
|
#define HID_RESERVED 0x00
|
||||||
#define HID_ERROR_ROLL_OVER 0x01
|
#define HID_ERROR_ROLL_OVER 0x01
|
||||||
|
|||||||
@@ -269,25 +269,21 @@ static void test_parse_integer_with_suffix(void) {
|
|||||||
|
|
||||||
char buf[32];
|
char buf[32];
|
||||||
|
|
||||||
int r = snprintf(buf, sizeof(buf), "%ldk", LONG_MAX / 2000);
|
sprintf(buf, "%ldk", LONG_MAX / 2000);
|
||||||
assert(r >= 0 && (size_t) r < sizeof(buf));
|
|
||||||
ok = sc_str_parse_integer_with_suffix(buf, &value);
|
ok = sc_str_parse_integer_with_suffix(buf, &value);
|
||||||
assert(ok);
|
assert(ok);
|
||||||
assert(value == LONG_MAX / 2000 * 1000);
|
assert(value == LONG_MAX / 2000 * 1000);
|
||||||
|
|
||||||
r = snprintf(buf, sizeof(buf), "%ldm", LONG_MAX / 2000);
|
sprintf(buf, "%ldm", LONG_MAX / 2000);
|
||||||
assert(r >= 0 && (size_t) r < sizeof(buf));
|
|
||||||
ok = sc_str_parse_integer_with_suffix(buf, &value);
|
ok = sc_str_parse_integer_with_suffix(buf, &value);
|
||||||
assert(!ok);
|
assert(!ok);
|
||||||
|
|
||||||
r = snprintf(buf, sizeof(buf), "%ldk", LONG_MIN / 2000);
|
sprintf(buf, "%ldk", LONG_MIN / 2000);
|
||||||
assert(r >= 0 && (size_t) r < sizeof(buf));
|
|
||||||
ok = sc_str_parse_integer_with_suffix(buf, &value);
|
ok = sc_str_parse_integer_with_suffix(buf, &value);
|
||||||
assert(ok);
|
assert(ok);
|
||||||
assert(value == LONG_MIN / 2000 * 1000);
|
assert(value == LONG_MIN / 2000 * 1000);
|
||||||
|
|
||||||
r = snprintf(buf, sizeof(buf), "%ldm", LONG_MIN / 2000);
|
sprintf(buf, "%ldm", LONG_MIN / 2000);
|
||||||
assert(r >= 0 && (size_t) r < sizeof(buf));
|
|
||||||
ok = sc_str_parse_integer_with_suffix(buf, &value);
|
ok = sc_str_parse_integer_with_suffix(buf, &value);
|
||||||
assert(!ok);
|
assert(!ok);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ If several displays are available on the Android device, it is possible to
|
|||||||
select the display to mirror:
|
select the display to mirror:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
scrcpy --display-id=1
|
scrcpy --display=1
|
||||||
```
|
```
|
||||||
|
|
||||||
The list of display ids can be retrieved by:
|
The list of display ids can be retrieved by:
|
||||||
|
|||||||
@@ -6,9 +6,7 @@ import android.annotation.SuppressLint;
|
|||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.hardware.camera2.CameraAccessException;
|
import android.hardware.camera2.CameraAccessException;
|
||||||
import android.hardware.camera2.CameraCaptureSession;
|
import android.hardware.camera2.CameraCaptureSession;
|
||||||
import android.hardware.camera2.CameraCharacteristics;
|
|
||||||
import android.hardware.camera2.CameraDevice;
|
import android.hardware.camera2.CameraDevice;
|
||||||
import android.hardware.camera2.CameraManager;
|
|
||||||
import android.hardware.camera2.CaptureFailure;
|
import android.hardware.camera2.CaptureFailure;
|
||||||
import android.hardware.camera2.CaptureRequest;
|
import android.hardware.camera2.CaptureRequest;
|
||||||
import android.hardware.camera2.params.OutputConfiguration;
|
import android.hardware.camera2.params.OutputConfiguration;
|
||||||
@@ -28,25 +26,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
|
|
||||||
public class CameraCapture extends SurfaceCapture {
|
public class CameraCapture extends SurfaceCapture {
|
||||||
|
|
||||||
public static class CameraSelection {
|
private final String cameraId;
|
||||||
private String explicitCameraId;
|
|
||||||
private CameraFacing cameraFacing;
|
|
||||||
|
|
||||||
public CameraSelection(String explicitCameraId, CameraFacing cameraFacing) {
|
|
||||||
this.explicitCameraId = explicitCameraId;
|
|
||||||
this.cameraFacing = cameraFacing;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean hasId() {
|
|
||||||
return explicitCameraId != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean hasProperties() {
|
|
||||||
return cameraFacing != null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final CameraSelection cameraSelection;
|
|
||||||
private final Size explicitSize;
|
private final Size explicitSize;
|
||||||
|
|
||||||
private HandlerThread cameraThread;
|
private HandlerThread cameraThread;
|
||||||
@@ -56,8 +36,8 @@ public class CameraCapture extends SurfaceCapture {
|
|||||||
|
|
||||||
private final AtomicBoolean disconnected = new AtomicBoolean();
|
private final AtomicBoolean disconnected = new AtomicBoolean();
|
||||||
|
|
||||||
public CameraCapture(CameraSelection cameraSelection, Size explicitSize) {
|
public CameraCapture(String cameraId, Size explicitSize) {
|
||||||
this.cameraSelection = cameraSelection;
|
this.cameraId = cameraId;
|
||||||
this.explicitSize = explicitSize;
|
this.explicitSize = explicitSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,49 +49,12 @@ public class CameraCapture extends SurfaceCapture {
|
|||||||
cameraExecutor = new HandlerExecutor(cameraHandler);
|
cameraExecutor = new HandlerExecutor(cameraHandler);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String cameraId = selectCamera(cameraSelection);
|
|
||||||
if (cameraId == null) {
|
|
||||||
throw new IOException("No matching camera found");
|
|
||||||
}
|
|
||||||
|
|
||||||
Ln.i("Using camera '" + cameraId + "'");
|
|
||||||
cameraDevice = openCamera(cameraId);
|
cameraDevice = openCamera(cameraId);
|
||||||
} catch (CameraAccessException | InterruptedException e) {
|
} catch (CameraAccessException | InterruptedException e) {
|
||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String selectCamera(CameraSelection cameraSelection) throws CameraAccessException {
|
|
||||||
if (cameraSelection.hasId()) {
|
|
||||||
return cameraSelection.explicitCameraId;
|
|
||||||
}
|
|
||||||
|
|
||||||
CameraManager cameraManager = ServiceManager.getCameraManager();
|
|
||||||
|
|
||||||
String[] cameraIds = cameraManager.getCameraIdList();
|
|
||||||
if (!cameraSelection.hasProperties()) {
|
|
||||||
// Use the first one
|
|
||||||
return cameraIds.length > 0 ? cameraIds[0] : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String cameraId : cameraIds) {
|
|
||||||
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
|
|
||||||
|
|
||||||
if (cameraSelection.cameraFacing != null) {
|
|
||||||
int facing = characteristics.get(CameraCharacteristics.LENS_FACING);
|
|
||||||
if (cameraSelection.cameraFacing.value() != facing) {
|
|
||||||
// Does not match
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return cameraId;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not found
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(Surface surface) throws IOException {
|
public void start(Surface surface) throws IOException {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
package com.genymobile.scrcpy;
|
|
||||||
|
|
||||||
import android.hardware.camera2.CameraCharacteristics;
|
|
||||||
|
|
||||||
public enum CameraFacing {
|
|
||||||
FRONT("front", CameraCharacteristics.LENS_FACING_FRONT),
|
|
||||||
BACK("back", CameraCharacteristics.LENS_FACING_BACK),
|
|
||||||
EXTERNAL("external", CameraCharacteristics.LENS_FACING_EXTERNAL);
|
|
||||||
|
|
||||||
private final String name;
|
|
||||||
private final int value;
|
|
||||||
|
|
||||||
CameraFacing(String name, int value) {
|
|
||||||
this.name = name;
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
int value() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CameraFacing findByName(String name) {
|
|
||||||
for (CameraFacing facing : CameraFacing.values()) {
|
|
||||||
if (name.equals(facing.name)) {
|
|
||||||
return facing;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -54,7 +54,7 @@ public final class LogUtils {
|
|||||||
builder.append("\n (none)");
|
builder.append("\n (none)");
|
||||||
} else {
|
} else {
|
||||||
for (int id : displayIds) {
|
for (int id : displayIds) {
|
||||||
builder.append("\n --display-id=").append(id).append(" (");
|
builder.append("\n --display=").append(id).append(" (");
|
||||||
DisplayInfo displayInfo = displayManager.getDisplayInfo(id);
|
DisplayInfo displayInfo = displayManager.getDisplayInfo(id);
|
||||||
if (displayInfo != null) {
|
if (displayInfo != null) {
|
||||||
Size size = displayInfo.getSize();
|
Size size = displayInfo.getSize();
|
||||||
@@ -90,7 +90,7 @@ public final class LogUtils {
|
|||||||
builder.append("\n (none)");
|
builder.append("\n (none)");
|
||||||
} else {
|
} else {
|
||||||
for (String id : cameraIds) {
|
for (String id : cameraIds) {
|
||||||
builder.append("\n --video-source=camera --camera-id=").append(id);
|
builder.append("\n --video-source=camera --camera=").append(id);
|
||||||
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(id);
|
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(id);
|
||||||
int facing = characteristics.get(CameraCharacteristics.LENS_FACING);
|
int facing = characteristics.get(CameraCharacteristics.LENS_FACING);
|
||||||
builder.append(" (").append(getCameraFacingName(facing)).append(", ");
|
builder.append(" (").append(getCameraFacingName(facing)).append(", ");
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ public class Options {
|
|||||||
private int displayId;
|
private int displayId;
|
||||||
private String cameraId;
|
private String cameraId;
|
||||||
private Size cameraSize;
|
private Size cameraSize;
|
||||||
private CameraFacing cameraFacing;
|
|
||||||
private boolean showTouches;
|
private boolean showTouches;
|
||||||
private boolean stayAwake;
|
private boolean stayAwake;
|
||||||
private List<CodecOption> videoCodecOptions;
|
private List<CodecOption> videoCodecOptions;
|
||||||
@@ -127,10 +126,6 @@ public class Options {
|
|||||||
return cameraSize;
|
return cameraSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CameraFacing getCameraFacing() {
|
|
||||||
return cameraFacing;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getShowTouches() {
|
public boolean getShowTouches() {
|
||||||
return showTouches;
|
return showTouches;
|
||||||
}
|
}
|
||||||
@@ -297,9 +292,7 @@ public class Options {
|
|||||||
options.tunnelForward = Boolean.parseBoolean(value);
|
options.tunnelForward = Boolean.parseBoolean(value);
|
||||||
break;
|
break;
|
||||||
case "crop":
|
case "crop":
|
||||||
if (!value.isEmpty()) {
|
options.crop = parseCrop(value);
|
||||||
options.crop = parseCrop(value);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case "control":
|
case "control":
|
||||||
options.control = Boolean.parseBoolean(value);
|
options.control = Boolean.parseBoolean(value);
|
||||||
@@ -356,22 +349,11 @@ public class Options {
|
|||||||
options.listCameraSizes = Boolean.parseBoolean(value);
|
options.listCameraSizes = Boolean.parseBoolean(value);
|
||||||
break;
|
break;
|
||||||
case "camera_id":
|
case "camera_id":
|
||||||
if (!value.isEmpty()) {
|
options.cameraId = value;
|
||||||
options.cameraId = value;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case "camera_size":
|
case "camera_size":
|
||||||
options.cameraSize = parseSize(value);
|
options.cameraSize = parseSize(value);
|
||||||
break;
|
break;
|
||||||
case "camera_facing":
|
|
||||||
if (!value.isEmpty()) {
|
|
||||||
CameraFacing facing = CameraFacing.findByName(value);
|
|
||||||
if (facing == null) {
|
|
||||||
throw new IllegalArgumentException("Camera facing " + value + " not supported");
|
|
||||||
}
|
|
||||||
options.cameraFacing = facing;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "send_device_meta":
|
case "send_device_meta":
|
||||||
options.sendDeviceMeta = Boolean.parseBoolean(value);
|
options.sendDeviceMeta = Boolean.parseBoolean(value);
|
||||||
break;
|
break;
|
||||||
@@ -403,6 +385,9 @@ public class Options {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Rect parseCrop(String crop) {
|
private static Rect parseCrop(String crop) {
|
||||||
|
if (crop.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
// input format: "width:height:x:y"
|
// input format: "width:height:x:y"
|
||||||
String[] tokens = crop.split(":");
|
String[] tokens = crop.split(":");
|
||||||
if (tokens.length != 4) {
|
if (tokens.length != 4) {
|
||||||
|
|||||||
@@ -138,9 +138,7 @@ public final class Server {
|
|||||||
if (options.getVideoSource() == VideoSource.DISPLAY) {
|
if (options.getVideoSource() == VideoSource.DISPLAY) {
|
||||||
surfaceCapture = new ScreenCapture(device);
|
surfaceCapture = new ScreenCapture(device);
|
||||||
} else {
|
} else {
|
||||||
CameraCapture.CameraSelection cameraSelection = new CameraCapture.CameraSelection(options.getCameraId(),
|
surfaceCapture = new CameraCapture(options.getCameraId(), options.getCameraSize());
|
||||||
options.getCameraFacing());
|
|
||||||
surfaceCapture = new CameraCapture(cameraSelection, options.getCameraSize());
|
|
||||||
}
|
}
|
||||||
SurfaceEncoder surfaceEncoder = new SurfaceEncoder(surfaceCapture, videoStreamer, options.getVideoBitRate(), options.getMaxFps(),
|
SurfaceEncoder surfaceEncoder = new SurfaceEncoder(surfaceCapture, videoStreamer, options.getVideoBitRate(), options.getMaxFps(),
|
||||||
options.getVideoCodecOptions(), options.getVideoEncoder(), options.getDownsizeOnError());
|
options.getVideoCodecOptions(), options.getVideoEncoder(), options.getDownsizeOnError());
|
||||||
|
|||||||
Reference in New Issue
Block a user