Compare commits
2 Commits
v1.17
...
racecond_o
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d82db2e69e | ||
|
|
305b4b2b81 |
36
FAQ.md
36
FAQ.md
@@ -201,39 +201,3 @@ scrcpy -m 800
|
||||
```
|
||||
|
||||
You could also try another [encoder](README.md#encoder).
|
||||
|
||||
|
||||
## Command line on Windows
|
||||
|
||||
Some Windows users are not familiar with the command line. Here is how to open a
|
||||
terminal and run `scrcpy` with arguments:
|
||||
|
||||
1. Press <kbd>Windows</kbd>+<kbd>r</kbd>, this opens a dialog box.
|
||||
2. Type `cmd` and press <kbd>Enter</kbd>, this opens a terminal.
|
||||
3. Go to your _scrcpy_ directory, by typing (adapt the path):
|
||||
|
||||
```bat
|
||||
cd C:\Users\user\Downloads\scrcpy-win64-xxx
|
||||
```
|
||||
|
||||
and press <kbd>Enter</kbd>
|
||||
4. Type your command. For example:
|
||||
|
||||
```bat
|
||||
scrcpy --record file.mkv
|
||||
```
|
||||
|
||||
If you plan to always use the same arguments, create a file `myscrcpy.bat`
|
||||
(enable [show file extensions] to avoid confusion) in the `scrcpy` directory,
|
||||
containing your command. For example:
|
||||
|
||||
```bat
|
||||
scrcpy --prefer-text --turn-screen-off --stay-awake
|
||||
```
|
||||
|
||||
Then just double-click on that file.
|
||||
|
||||
You could also edit (a copy of) `scrcpy-console.bat` or `scrcpy-noconsole.vbs`
|
||||
to add some arguments.
|
||||
|
||||
[show file extensions]: https://www.howtogeek.com/205086/beginner-how-to-make-windows-show-file-extensions/
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -188,7 +188,7 @@
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright (C) 2018 Genymobile
|
||||
Copyright (C) 2018-2021 Romain Vimont
|
||||
Copyright (C) 2018-2020 Romain Vimont
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -675,7 +675,7 @@ Baca [halaman pengembang].
|
||||
## Lisensi
|
||||
|
||||
Copyright (C) 2018 Genymobile
|
||||
Copyright (C) 2018-2021 Romain Vimont
|
||||
Copyright (C) 2018-2020 Romain Vimont
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -477,7 +477,7 @@ _²화면이 꺼진 상태에서 우클릭 시 다시 켜지며, 그 외의 상
|
||||
## 라이선스
|
||||
|
||||
Copyright (C) 2018 Genymobile
|
||||
Copyright (C) 2018-2021 Romain Vimont
|
||||
Copyright (C) 2018-2020 Romain Vimont
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
10
README.md
10
README.md
@@ -202,8 +202,6 @@ scrcpy --lock-video-orientation 3 # 90° clockwise
|
||||
|
||||
This affects recording orientation.
|
||||
|
||||
The [window may also be rotated](#rotation) independently.
|
||||
|
||||
|
||||
#### Encoder
|
||||
|
||||
@@ -409,9 +407,9 @@ Note that _scrcpy_ manages 3 different rotations:
|
||||
- <kbd>MOD</kbd>+<kbd>r</kbd> requests the device to switch between portrait
|
||||
and landscape (the current running app may refuse, if it does support the
|
||||
requested orientation).
|
||||
- [`--lock-video-orientation`](#lock-video-orientation) changes the mirroring
|
||||
orientation (the orientation of the video sent from the device to the
|
||||
computer). This affects the recording.
|
||||
- `--lock-video-orientation` changes the mirroring orientation (the orientation
|
||||
of the video sent from the device to the computer). This affects the
|
||||
recording.
|
||||
- `--rotation` (or <kbd>MOD</kbd>+<kbd>←</kbd>/<kbd>MOD</kbd>+<kbd>→</kbd>)
|
||||
rotates only the window content. This affects only the display, not the
|
||||
recording.
|
||||
@@ -768,7 +766,7 @@ Read the [developers page].
|
||||
## Licence
|
||||
|
||||
Copyright (C) 2018 Genymobile
|
||||
Copyright (C) 2018-2021 Romain Vimont
|
||||
Copyright (C) 2018-2020 Romain Vimont
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -508,7 +508,7 @@ Leia a [developers page].
|
||||
## Licença
|
||||
|
||||
Copyright (C) 2018 Genymobile
|
||||
Copyright (C) 2018-2021 Romain Vimont
|
||||
Copyright (C) 2018-2020 Romain Vimont
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -703,7 +703,7 @@ _³需要安卓版本 Android >= 7。_
|
||||
## 许可协议
|
||||
|
||||
Copyright (C) 2018 Genymobile
|
||||
Copyright (C) 2018-2021 Romain Vimont
|
||||
Copyright (C) 2018-2020 Romain Vimont
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -682,7 +682,7 @@ _³只支援 Android 7+。_
|
||||
## Licence
|
||||
|
||||
Copyright (C) 2018 Genymobile
|
||||
Copyright (C) 2018-2021 Romain Vimont
|
||||
Copyright (C) 2018-2020 Romain Vimont
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include "util/log.h"
|
||||
#include "util/net.h"
|
||||
|
||||
static struct server server;
|
||||
static struct server server = SERVER_INITIALIZER;
|
||||
static struct screen screen = SCREEN_INITIALIZER;
|
||||
static struct fps_counter fps_counter;
|
||||
static struct video_buffer video_buffer;
|
||||
@@ -304,19 +304,6 @@ av_log_callback(void *avcl, int level, const char *fmt, va_list vl) {
|
||||
|
||||
bool
|
||||
scrcpy(const struct scrcpy_options *options) {
|
||||
if (!server_init(&server)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool server_started = false;
|
||||
bool fps_counter_initialized = false;
|
||||
bool video_buffer_initialized = false;
|
||||
bool file_handler_initialized = false;
|
||||
bool recorder_initialized = false;
|
||||
bool stream_started = false;
|
||||
bool controller_initialized = false;
|
||||
bool controller_started = false;
|
||||
|
||||
bool record = !!options->record_filename;
|
||||
struct server_params params = {
|
||||
.log_level = options->log_level,
|
||||
@@ -335,10 +322,18 @@ scrcpy(const struct scrcpy_options *options) {
|
||||
.force_adb_forward = options->force_adb_forward,
|
||||
};
|
||||
if (!server_start(&server, options->serial, ¶ms)) {
|
||||
goto end;
|
||||
return false;
|
||||
}
|
||||
|
||||
server_started = true;
|
||||
bool ret = false;
|
||||
|
||||
bool fps_counter_initialized = false;
|
||||
bool video_buffer_initialized = false;
|
||||
bool file_handler_initialized = false;
|
||||
bool recorder_initialized = false;
|
||||
bool stream_started = false;
|
||||
bool controller_initialized = false;
|
||||
bool controller_started = false;
|
||||
|
||||
if (!sdl_init_and_configure(options->display, options->render_driver,
|
||||
options->disable_screensaver)) {
|
||||
@@ -449,7 +444,7 @@ scrcpy(const struct scrcpy_options *options) {
|
||||
|
||||
input_manager_init(&input_manager, options);
|
||||
|
||||
bool ret = event_loop(options);
|
||||
ret = event_loop(options);
|
||||
LOGD("quit...");
|
||||
|
||||
screen_destroy(&screen);
|
||||
@@ -470,10 +465,8 @@ end:
|
||||
fps_counter_interrupt(&fps_counter);
|
||||
}
|
||||
|
||||
if (server_started) {
|
||||
// shutdown the sockets and kill the server
|
||||
server_stop(&server);
|
||||
}
|
||||
// shutdown the sockets and kill the server
|
||||
server_stop(&server);
|
||||
|
||||
// now that the sockets are shutdown, the stream and controller are
|
||||
// interrupted, we can join them
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "command.h"
|
||||
#include "util/lock.h"
|
||||
#include "util/log.h"
|
||||
#include "util/net.h"
|
||||
#include "util/str_util.h"
|
||||
@@ -354,51 +353,15 @@ close_socket(socket_t socket) {
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
server_init(struct server *server) {
|
||||
server->serial = NULL;
|
||||
server->process = PROCESS_NONE;
|
||||
server->wait_server_thread = NULL;
|
||||
atomic_flag_clear_explicit(&server->server_socket_closed,
|
||||
memory_order_relaxed);
|
||||
|
||||
server->mutex = SDL_CreateMutex();
|
||||
if (!server->mutex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
server->process_terminated_cond = SDL_CreateCond();
|
||||
if (!server->process_terminated_cond) {
|
||||
SDL_DestroyMutex(server->mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
server->process_terminated = false;
|
||||
|
||||
server->server_socket = INVALID_SOCKET;
|
||||
server->video_socket = INVALID_SOCKET;
|
||||
server->control_socket = INVALID_SOCKET;
|
||||
|
||||
server->port_range.first = 0;
|
||||
server->port_range.last = 0;
|
||||
server->local_port = 0;
|
||||
|
||||
server->tunnel_enabled = false;
|
||||
server->tunnel_forward = false;
|
||||
|
||||
return true;
|
||||
*server = (struct server) SERVER_INITIALIZER;
|
||||
}
|
||||
|
||||
static int
|
||||
run_wait_server(void *data) {
|
||||
struct server *server = data;
|
||||
cmd_simple_wait(server->process, NULL); // ignore exit code
|
||||
|
||||
mutex_lock(server->mutex);
|
||||
server->process_terminated = true;
|
||||
cond_signal(server->process_terminated_cond);
|
||||
mutex_unlock(server->mutex);
|
||||
|
||||
// no need for synchronization, server_socket is initialized before this
|
||||
// thread was created
|
||||
if (server->server_socket != INVALID_SOCKET
|
||||
@@ -535,34 +498,10 @@ server_stop(struct server *server) {
|
||||
disable_tunnel(server);
|
||||
}
|
||||
|
||||
// Give some delay for the server to terminate properly
|
||||
mutex_lock(server->mutex);
|
||||
int r = 0;
|
||||
if (!server->process_terminated) {
|
||||
#define WATCHDOG_DELAY_MS 1000
|
||||
r = cond_wait_timeout(server->process_terminated_cond,
|
||||
server->mutex,
|
||||
WATCHDOG_DELAY_MS);
|
||||
}
|
||||
mutex_unlock(server->mutex);
|
||||
|
||||
// After this delay, kill the server if it's not dead already.
|
||||
// On some devices, closing the sockets is not sufficient to wake up the
|
||||
// blocking calls while the device is asleep.
|
||||
if (r == SDL_MUTEX_TIMEDOUT) {
|
||||
// FIXME There is a race condition here: there is a small chance that
|
||||
// the process is already terminated, and the PID assigned to a new
|
||||
// process.
|
||||
LOGW("Killing the server...");
|
||||
cmd_terminate(server->process);
|
||||
}
|
||||
|
||||
SDL_WaitThread(server->wait_server_thread, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
server_destroy(struct server *server) {
|
||||
SDL_free(server->serial);
|
||||
SDL_DestroyCond(server->process_terminated_cond);
|
||||
SDL_DestroyMutex(server->mutex);
|
||||
}
|
||||
|
||||
@@ -18,11 +18,6 @@ struct server {
|
||||
process_t process;
|
||||
SDL_Thread *wait_server_thread;
|
||||
atomic_flag server_socket_closed;
|
||||
|
||||
SDL_mutex *mutex;
|
||||
SDL_cond *process_terminated_cond;
|
||||
bool process_terminated;
|
||||
|
||||
socket_t server_socket; // only used if !tunnel_forward
|
||||
socket_t video_socket;
|
||||
socket_t control_socket;
|
||||
@@ -32,6 +27,23 @@ struct server {
|
||||
bool tunnel_forward; // use "adb forward" instead of "adb reverse"
|
||||
};
|
||||
|
||||
#define SERVER_INITIALIZER { \
|
||||
.serial = NULL, \
|
||||
.process = PROCESS_NONE, \
|
||||
.wait_server_thread = NULL, \
|
||||
.server_socket_closed = ATOMIC_FLAG_INIT, \
|
||||
.server_socket = INVALID_SOCKET, \
|
||||
.video_socket = INVALID_SOCKET, \
|
||||
.control_socket = INVALID_SOCKET, \
|
||||
.port_range = { \
|
||||
.first = 0, \
|
||||
.last = 0, \
|
||||
}, \
|
||||
.local_port = 0, \
|
||||
.tunnel_enabled = false, \
|
||||
.tunnel_forward = false, \
|
||||
}
|
||||
|
||||
struct server_params {
|
||||
enum sc_log_level log_level;
|
||||
const char *crop;
|
||||
@@ -50,7 +62,7 @@ struct server_params {
|
||||
};
|
||||
|
||||
// init default values
|
||||
bool
|
||||
void
|
||||
server_init(struct server *server);
|
||||
|
||||
// push, enable tunnel et start the server
|
||||
|
||||
@@ -56,7 +56,7 @@ cmd_execute(const char *const argv[], HANDLE *handle) {
|
||||
|
||||
bool
|
||||
cmd_terminate(HANDLE handle) {
|
||||
return TerminateProcess(handle, 1);
|
||||
return TerminateProcess(handle, 1) && CloseHandle(handle);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -70,7 +70,6 @@ cmd_simple_wait(HANDLE handle, DWORD *exit_code) {
|
||||
if (exit_code) {
|
||||
*exit_code = code;
|
||||
}
|
||||
CloseHandle(handle);
|
||||
return !code;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,4 +17,4 @@ endian = 'little'
|
||||
[properties]
|
||||
prebuilt_ffmpeg_shared = 'ffmpeg-4.3.1-win32-shared'
|
||||
prebuilt_ffmpeg_dev = 'ffmpeg-4.3.1-win32-dev'
|
||||
prebuilt_sdl2 = 'SDL2-2.0.14/i686-w64-mingw32'
|
||||
prebuilt_sdl2 = 'SDL2-2.0.12/i686-w64-mingw32'
|
||||
|
||||
@@ -17,4 +17,4 @@ endian = 'little'
|
||||
[properties]
|
||||
prebuilt_ffmpeg_shared = 'ffmpeg-4.3.1-win64-shared'
|
||||
prebuilt_ffmpeg_dev = 'ffmpeg-4.3.1-win64-dev'
|
||||
prebuilt_sdl2 = 'SDL2-2.0.14/x86_64-w64-mingw32'
|
||||
prebuilt_sdl2 = 'SDL2-2.0.12/x86_64-w64-mingw32'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
project('scrcpy', 'c',
|
||||
version: '1.17',
|
||||
version: '1.16',
|
||||
meson_version: '>= 0.48',
|
||||
default_options: [
|
||||
'c_std=c11',
|
||||
|
||||
@@ -30,9 +30,9 @@ prepare-ffmpeg-dev-win64:
|
||||
ffmpeg-4.3.1-win64-dev
|
||||
|
||||
prepare-sdl2:
|
||||
@./prepare-dep https://libsdl.org/release/SDL2-devel-2.0.14-mingw.tar.gz \
|
||||
405eaff3eb18f2e08fe669ef9e63bc9a8710b7d343756f238619761e9b60407d \
|
||||
SDL2-2.0.14
|
||||
@./prepare-dep https://libsdl.org/release/SDL2-devel-2.0.12-mingw.tar.gz \
|
||||
e614a60f797e35ef9f3f96aef3dc6a1d786de3cc7ca6216f97e435c0b6aafc46 \
|
||||
SDL2-2.0.12
|
||||
|
||||
prepare-adb:
|
||||
@./prepare-dep https://dl.google.com/android/repository/platform-tools_r30.0.5-windows.zip \
|
||||
|
||||
@@ -102,7 +102,7 @@ dist-win32: build-server build-win32
|
||||
cp prebuilt-deps/platform-tools/adb.exe "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
cp prebuilt-deps/platform-tools/AdbWinApi.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
cp prebuilt-deps/platform-tools/AdbWinUsbApi.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
cp prebuilt-deps/SDL2-2.0.14/i686-w64-mingw32/bin/SDL2.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
cp prebuilt-deps/SDL2-2.0.12/i686-w64-mingw32/bin/SDL2.dll "$(DIST)/$(WIN32_TARGET_DIR)/"
|
||||
|
||||
dist-win64: build-server build-win64
|
||||
mkdir -p "$(DIST)/$(WIN64_TARGET_DIR)"
|
||||
@@ -118,7 +118,7 @@ dist-win64: build-server build-win64
|
||||
cp prebuilt-deps/platform-tools/adb.exe "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
cp prebuilt-deps/platform-tools/AdbWinApi.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
cp prebuilt-deps/platform-tools/AdbWinUsbApi.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
cp prebuilt-deps/SDL2-2.0.14/x86_64-w64-mingw32/bin/SDL2.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
cp prebuilt-deps/SDL2-2.0.12/x86_64-w64-mingw32/bin/SDL2.dll "$(DIST)/$(WIN64_TARGET_DIR)/"
|
||||
|
||||
zip-win32: dist-win32
|
||||
cd "$(DIST)/$(WIN32_TARGET_DIR)"; \
|
||||
@@ -1,2 +1,2 @@
|
||||
#!/bin/bash
|
||||
make -f release.mk
|
||||
make -f release.make
|
||||
|
||||
@@ -6,8 +6,8 @@ android {
|
||||
applicationId "com.genymobile.scrcpy"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 30
|
||||
versionCode 20
|
||||
versionName "1.17"
|
||||
versionCode 19
|
||||
versionName "1.16"
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
buildTypes {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
set -e
|
||||
|
||||
SCRCPY_DEBUG=false
|
||||
SCRCPY_VERSION_NAME=1.17
|
||||
SCRCPY_VERSION_NAME=1.16
|
||||
|
||||
PLATFORM=${ANDROID_PLATFORM:-30}
|
||||
BUILD_TOOLS=${ANDROID_BUILD_TOOLS:-30.0.0}
|
||||
|
||||
Reference in New Issue
Block a user