- 16 2月, 2018 3 次提交
-
-
由 Romain Vimont 提交于
SDL_net is not very suitable for scrcpy. For example, SDLNet_TCP_Accept() is non-blocking, so we have to wrap it by calling many SDL_Net-specific functions to make it blocking. But above all, SDLNet_TCP_Open() is a server socket only when no IP is provided; otherwise, it's a client socket. Therefore, it is not possible to create a server socket bound to localhost, so it accepts connections from anywhere. This is a problem for scrcpy, because on start, the application listens for nearly 1 second until it accepts the first connection, supposedly from the device. If someone on the local network manages to connect to the server socket first, then they can stream arbitrary H.264 video. This may be troublesome, for example during a public presentation ;-) Provide our own simplified API (net.h) instead, implemented for the different platforms.
-
由 Romain Vimont 提交于
The syntax was correct, but less readable, and it unnecessarily zeroed the fields other than "type". Create the event properly, from a separate method.
-
由 Romain Vimont 提交于
Executing commands (like "adb push") created a new terminal window on Windows. Avoid it.
-
- 15 2月, 2018 13 次提交
-
-
由 Romain Vimont 提交于
Pressing Ctrl+x resizes the window to remove black borders, "optimal" is not well-defined.
-
由 Romain Vimont 提交于
screen_render() should not be called on initialization: 1. it is useless, since the window is hidden until the first frame; 2. it writes an empty texture (probably green) to the renderer.
-
由 Romain Vimont 提交于
Disable FPS counter on start, and use Ctrl+i to enable/disable it.
-
由 Romain Vimont 提交于
The "screen control" handled user input, which happened to be only used to control the screen. The controller and screen were passed to every function. Instead, group them in a struct input_manager. The purpose is to add a new shortcut to enable/disable FPS counter. This feature is not related to "screen control", and will require access to the "frames" instance.
-
由 Romain Vimont 提交于
The descriptions are displayed in the result of: mesonconf builddir
-
由 Romain Vimont 提交于
It can be initially configured by: meson builddir -Dskip_frames=false Or on an existing builddir by: mesonconf builddir -Dskip_frames=false
-
由 Romain Vimont 提交于
Remove frame counter from scrcpy.c and add a new FPS counter, logging as INFO the measured frame rate every second (on new frame).
-
由 Romain Vimont 提交于
On error, a message is printed. If we print usage afterwards, it's easy to miss it.
-
由 Romain Vimont 提交于
The device serial was provided as a positional argument: scrcpy 0123456789abcdef Instead, expose it as an optional argument, -s or --serial: scrcpy -s 0123456789abcdef This avoids inconsistency between platforms when the positional argument is passed before the options (which is undefined).
-
由 Romain Vimont 提交于
To avoid a big switch/case, implement the argument parsing logic in separate static functions.
-
由 Romain Vimont 提交于
For clarity and consistency across the application, return SDL_TRUE (instead of 0) on success and SDL_FALSE on failure (instead of non-zero).
-
由 Romain Vimont 提交于
For readability, sort the command-line arguments parsing by letter.
-
由 Romain Vimont 提交于
Add a script to simplify the execution of scrcpy generated in a specific build directory. To run scrcpy generated in builddir, with a video size of 1024: ./run builddir -m 1024
-
- 14 2月, 2018 5 次提交
-
-
由 Romain Vimont 提交于
Expose a 'prebuilt_server' option to pass the path of the prebuilt binary, so that the build does not require Android SDK. Usage: meson builddir -Dprebuilt_server=/tmp/my_prebuilt_server.jar
-
由 Romain Vimont 提交于
Older versions of Meson are too limited, and it's simple to install a newer version ("pip3 install meson").
-
由 Romain Vimont 提交于
The custom target used to invoke Gradle from Meson should always be built, otherwise, the server would not be rebuilt on source changes. However, when enabling "build_always", gradle is invoked as root on "sudo ninja install" after "ninja", so it downloads the whole Gradle world into /root/.gradle. To avoid the problem, just do not call gradle if the effective user id is 0.
-
由 Romain Vimont 提交于
Since Meson 0.44, subproject_dir may not be '.' anymore. This implies we must move app/ and server/ to a subprojects/ directory, which requires to also change some gradle files. Instead, just use subdir(), with options to disable building of the app or the server.
-
由 Romain Vimont 提交于
The client was built with Meson, the server with Gradle, and were run by a Makefile. Add a Meson script for the server (which delegates to Gradle), and a parent script to build and install both the client and the server to the system, typically with: meson --buildtype release build cd build ninja sudo ninja install In addition, use a separate Makefile to build a "portable" version of the application (where the client expects the server to be in the current directory). Typically: make release-portable cd dist/scrcpy ./scrcpy This is especially useful for Windows builds, which are not "installed".
-
- 13 2月, 2018 4 次提交
-
-
由 Romain Vimont 提交于
The current meson version is able to generate a config.h from a configuration data object without any template. However, older versions of meson require a template, so provide it for compatibility.
-
由 Romain Vimont 提交于
Use macros to wrap SDL_Log* functions with the "application" category.
-
由 Romain Vimont 提交于
Old versions of meson do not support set_quoted(). Replace the call by the old-fashioned manual quotation.
-
由 Romain Vimont 提交于
Print the logs only if their level is not under the threshold, which is defined to INFO in release mode and DEBUG in debug mode.
-
- 12 2月, 2018 6 次提交
-
-
由 Romain Vimont 提交于
CloseHandle() does not terminate the process. TerminateProcess() does.
-
由 Romain Vimont 提交于
All our logs should use APPLICATION category. The logs for other categories are not printed by default under the "critical" level.
-
由 Romain Vimont 提交于
On our Windows machine, the mingw ld.exe does not support sanitizers. Exclude them from the default debug build.
-
由 Romain Vimont 提交于
In release mode, use the default log priorities.
-
由 Romain Vimont 提交于
Because why not.
-
由 Romain Vimont 提交于
Characters like 'é' or 'î' are not resolved by getEvents(). For example, getEvents("é") returns null. However, it is possible to decompose them. For example, getEvents("\u0301e") returns the events generating "é". Thank you Philippe! ;)
-
- 09 2月, 2018 9 次提交
-
-
由 Romain Vimont 提交于
The SDL clean up does not crash anymore on exit, probably since the memory corruption caused by calling SDLNet_TCP_Close() too early has been resolved.
-
由 Romain Vimont 提交于
Wait no more than 2 seconds for accepting the connection from the device, since it blocks the event loop, preventing to react to SIGTERM (Ctrl+C).
-
由 Romain Vimont 提交于
On startup, the client has to: 1. listen on a port 2. push and start the server to the device 3. wait for the server to connect (accept) 4. read device name and size 5. initialize SDL 6. initialize the window and renderer 7. show the window From the execution of the app_process command to start the server on the device, to the execution of the java main method, it takes ~800ms. As a consequence, step 3 also takes ~800ms on the client. Once complete, the client initializes SDL, which takes ~500ms. These two expensive actions are executed sequentially: HOST DEVICE listen on port | | push/start the server |----------------->|| app_process loads the jar accept the connection . ^ || . | || . | WASTE || . | OF || . | TIME || . | || . | || . v X execution of our java main connection accepted |<-----------------| connect to the host init SDL || | || ,----------------| send frames || |,---------------| || ||,--------------| || |||,-------------| || ||||,------------| init window/renderer | |||||,-----------| display frames |<++++++-----------| (many frames skipped) The rationale for step 3 occuring before step 5 is that initializing SDL replaces the SIGTERM handler to receive the event in the event loop, so pressing Ctrl+C during step 5 would not work (since it blocks the event loop). But this is not so important; let's parallelize the SDL initialization with the app_process execution (we'll just add a timeout to the connection): HOST DEVICE listen on port | | push/start the server |----------------->||app_process loads the jar init SDL || || || || || || || || || || || || accept the connection . || . X execution of our java main connection accepted |<-----------------| connect to the host init window/renderer | | display frames |<-----------------| send frames |<-----------------| In addition, show the window only once the first frame is available to avoid flickering (opening a black window for 100~200ms). Note: the window and renderer are initialized after the connection is accepted because they use the device information received from the device.
-
由 Romain Vimont 提交于
Turning the screen on is semantically associated to control(): only creating the EventController object should not turn the screen on.
-
由 Romain Vimont 提交于
Expose an initializer so that the caller does not have to guess what fields must be initialized.
-
由 Romain Vimont 提交于
SDLNet_TCP_Close() not only closes, but also release the resources. Therefore, we must not close the socket if another thread attempts to read it. For that purpose, move socket closing from server_stop() to server_destroy().
-
由 Romain Vimont 提交于
"make build-debug" will build with ASAN and USAN enabled.
-
由 Romain Vimont 提交于
Replace screen_update() by a higher-level screen_update_frame() handling the whole frame updating, so that scrcpy.c just call it without managing implementation details.
-
由 Romain Vimont 提交于
Do not wait 100ms anymore to let the server print any exception: we justly want to ignore them. Moreover, there is no nanosleep() on Windows, so this solve another problem.
-