Commit Graph

895 Commits

Author SHA1 Message Date
Romain Vimont 865ebb3862 Encode video using MediaCodec API
Replace screenrecord execution by manual screen encoding using the
MediaCodec API.

The "screenrecord" solution had several drawbacks:
 - screenrecord output is buffered, so tiny frames may not be accessible
   immediately;
 - it did not output a frame until the surface changed, leading to a
   black screen on start;
 - it is limited to 3 minutes recording, so it needed to be restarted;
 - screenrecord added black borders in the video when the requested
   dimensions did not preserve aspect-ratio exactly (sometimes
   unavoidable since video dimensions must be multiple of 8);
 - rotation handling was hacky (killing the process and starting a new
   one).

Handling the encoding manually allows to solve all these problems.
2018-01-31 19:51:43 +01:00
Romain Vimont 7ed334915e Register uncaught exception handler
Never miss an exception by using an uncaught exception handler.
2018-01-31 19:50:45 +01:00
Romain Vimont 8c4a454d68 Extract argument parsing
Move argument parsing to a separate method.
2018-01-31 19:49:49 +01:00
Romain Vimont 73831a0837 Use the Point class from the framework
Replace our custom Point class by android.graphics.Point.
2018-01-31 19:42:08 +01:00
Romain Vimont b67907e24e Convert server to an Android project
To simplify the device server-side build, use gradle to create an APK,
even if we use it as a simple jar, by running its main() method.
2018-01-30 12:01:36 +01:00
Romain Vimont 89f6a3cfe7 Handle resized video stream
Accept a parameter to limit the video size.

For instance, with "-m 960", the great side of the video will be scaled
down to 960 (if necessary), while the other side will be scaled down so
that the aspect ratio is preserved. Both dimensions must be a multiple
of 8, so black bands might be added, and the mouse positions must be
computed accordingly.
2018-01-29 15:40:33 +01:00
Romain Vimont 2c4ea6869e Do not use device as a singleton
The device instance should be able to store a state (e.g. the maximum
size requested by the user), so it should not be a singleton.
2018-01-29 15:00:15 +01:00
Romain Vimont 879941355d Swap position/point names
A point is a 2D vector. A position represent a point relative to the
screen size.
2018-01-29 14:52:22 +01:00
Romain Vimont f70359f14f Inject mouse events as touchscreen
As a mouse, some clicks on close prositions are sometimes not generated
on some devices.
2018-01-25 17:17:21 +01:00
Romain Vimont 1930c81062 Add toString() methods to java point classes
Useful for debugging.
2018-01-25 17:16:32 +01:00
Romain Vimont dca53ff931 Add missing source files in server Makefile
All classes were still built, but make was not able to detect changes on
missing files.
2018-01-25 17:15:40 +01:00
Romain Vimont 2aa15db210 Add shortcut to resize to ratio 1:1
Make Ctrl+g resize the window to the size of the video (pixel-perfect).
2018-01-24 09:56:42 +01:00
Romain Vimont ab2c3de9f5 Capture all Ctrl events
For consistency, capture all Ctrl events (not only those we react to).
2018-01-24 09:53:09 +01:00
Romain Vimont 2c35220618 Rename screen -> scrcpy -> main
Rename scrcpy.c to main.c (this file handles the command line parsing),
and screen.c to scrcpy.c (it exposes the entry point scrcpy()).
2018-01-23 16:44:59 +01:00
Romain Vimont 8984c1a7c4 Scale mouse events
The video screen size on the client may differ from the real device
screen size (e.g. the video stream may be scaled down). As a
consequence, mouse events must be scaled to match the real device
coordinates.

For this purpose, make the client send the video screen size along with
the absolute pointer location, and the server scale the location to
match the real device size before injecting mouse events.
2018-01-23 16:44:59 +01:00
Romain Vimont 11a60e5767 Keep screen info in cache
Currently, we only use screen information (width, height, rotation)
once at initialization, to send the device size to the client.

To be able to scale mouse events, make it accessible in memory. For this
purpose, replace the "static" DeviceUtil to a singleton Device, and
update it on every screen rotation.
2018-01-23 16:44:59 +01:00
Romain Vimont d7b00a9bab Move server-related functions to server.c
In addition to the functions to start/stop the server, move the
functions to push the jar and enable/disable the "adb reverse" tunnel.
2018-01-23 16:20:03 +01:00
Romain Vimont 3078894d1f Add debug log on new screenrecord execution
To easily notice problems with screenrecord execution, log every new
instance started.
2018-01-23 16:20:03 +01:00
Romain Vimont 7d67696b7e Extract server-related functions
To lighten screen.c, move start_server() and stop_server() to a separate
file.
2018-01-22 11:29:44 +01:00
Romain Vimont 52af91f6b0 Add unit tests for control event serialization
Test serialization of the 4 types of events (keycode, text, mouse,
scroll).
2018-01-19 16:55:39 +01:00
Romain Vimont 90c69d2c79 Use pointers-to-const where relevant
Explicitly declare const a function parameter intended to be read-only.
2018-01-19 15:13:38 +01:00
Romain Vimont 53cd59605a Ignore keycodes generating unwanted events
Ctrl, Alt, Shift and Meta should not be transmitted to the Android
device: they may generate unwanted events. For instance, resizing the
window using Alt+click will generate an Alt event which may open a menu
on the device.

All keycodes that generate a text input must also be excluded, to avoid
the text input to be written twice.
2018-01-19 14:09:15 +01:00
Romain Vimont 66b7a99db6 Fix includes windows-specific source
The header strutil.h is two levels above sys/win/command.c, and
SDL_log.h was missing.
2018-01-19 11:15:51 +01:00
Romain Vimont fbf2d34006 Add unit testing instructions in README 2018-01-18 17:28:05 +01:00
Romain Vimont f75c404a26 Add tests for strutil
Test our custom string handling functions.
2018-01-18 17:25:13 +01:00
Romain Vimont cabb102a04 Implement keyboard/mouse control
To control the device from the computer:
 - retrieve mouse and keyboard SDL events;
 - convert them to Android events;
 - serialize them;
 - send them on the same socket used by the video stream (but in the
 opposite direction);
 - deserialize the events on the Android side;
 - inject them using the InputManager.
2018-01-18 17:25:13 +01:00
Romain Vimont 6605ab8e23 Log to android logger and stdout/stderr 2018-01-18 16:53:20 +01:00
Romain Vimont 95591d2938 Move platform specific to sys/
Move unix/ and win/ to sys/, so that we can use android/ for android
headers without confusion.
2018-01-04 10:22:09 +01:00
Romain Vimont a919944372 Use _exit() instead of exit() in child process
exit() should not be called from within a child process, since it would
call functions registered with atexit(), and flush stdio streams. Use
_exit() instead.
2018-01-04 10:22:09 +01:00
Romain Vimont 07b3918129 Do not call SDL_Quit()
It may crash in i965_dri.so when calling SDL_Quit (probably a driver
bug). To avoid a segmentation fault, do not call SDL_Quit().
2017-12-19 14:12:11 +01:00
Romain Vimont a005df7b37 Always destroy in reverse order
For consistency and safety, always destroy objects in reverse order they
were initialized.
2017-12-19 14:11:55 +01:00
Romain Vimont de106747b6 Improve main() error handling
Parse the command-line arguments first, and do not ignore avformat
network init failure. At the end, deinit the avformat network.
2017-12-18 11:29:34 +01:00
Romain Vimont bb8afa9324 Fix comment about data sent over the socket
We now send the device name in addition to the screen dimensions on the
socket. Update the comment accordingly.
2017-12-18 11:27:55 +01:00
Romain Vimont d972a88c1a Optimize includes
Only include SDL_stdinc.h for SDL_bool, not the whole SDL.h.
2017-12-18 11:07:42 +01:00
Romain Vimont d5b349f670 Do not inline lockutil functions
This duplicates chars in the final binary.
2017-12-18 11:07:42 +01:00
Romain Vimont a9b276aa67 Remove useless forward declarations
The required headers are included anyway.
2017-12-15 17:19:43 +01:00
Romain Vimont b9c9466d65 Handle condition variable failure
Add condition variables function wrappers to handle unexpected failure.
2017-12-15 17:15:55 +01:00
Romain Vimont c4266e487b Rename (un)lock_mutex to mutex_(un)lock
For consistency, rename lock_mutex and unlock_mutex to mutex_lock and
mutex_unlock.
2017-12-15 17:15:55 +01:00
Romain Vimont ad667bfa20 Fix function signature
Use void for parameters (this project is in C).
2017-12-15 11:37:29 +01:00
Romain Vimont 37d88b8a6a Use SDL_bool return type instead of int
Many functions returned an int to indicate their success. For clarity,
use SDL_bool instead.
2017-12-15 11:27:54 +01:00
Romain Vimont 2b44052f80 Destroy condition variable on frames destruction
A condition variable was init for the "struct frames", but was never destroyed.
2017-12-15 11:12:02 +01:00
Romain Vimont 1a71c4ab1d Implement framework wrappers separately
Move the DeviceUtil internal static classes to public classes, in a
separate package (".wrappers").

This paves the way to implement InputManager properly.
2017-12-14 11:41:08 +01:00
Romain Vimont 39fd6ce518 Send device name on the socket
Make the server send the device name along with the width and height, so
that the client may use it as the window title.
2017-12-13 10:02:07 +01:00
Romain Vimont 9d141a7f50 Add README 2017-12-12 16:00:49 +01:00
Romain Vimont 54d9148a36 Initial commit
Start a new clean history from here.
2017-12-12 15:25:15 +01:00