Commit graph

286 commits

Author SHA1 Message Date
Romain Vimont
8f46e18426 Add --force-adb-forward
Add a command-line option to force "adb forward", without attempting
"adb reverse" first.

This is especially useful for using SSH tunnels without enabling remote
port forwarding.
2020-05-24 23:28:31 +02:00
Romain Vimont
a3ef461d73 Add cli option to set the verbosity level
The verbosity was set either to info (in release mode) or debug (in
debug mode).

Add a command-line argument to change it, so that users can enable debug
logs using the release:

    scrcpy -Vdebug
2020-05-24 22:01:51 +02:00
Tzah Mazuz
080a4ee365 Add --codec-options
Add a command-line parameter to pass custom options to the device
encoder (as a comma-separated list of "key[:type]=value").

The list of possible codec options is available in the Android
documentation:
<https://d.android.com/reference/android/media/MediaFormat>

PR #1325 <https://github.com/Genymobile/scrcpy/pull/1325>
Refs #1226 <https://github.com/Genymobile/scrcpy/pull/1226>

Co-authored-by: Romain Vimont <rom@rom1v.com>
2020-05-24 14:54:34 +02:00
Romain Vimont
e40532a376 Manually position and scale the content
Position and scale the content "manually" instead of relying on the
renderer "logical size".

This avoids possible rounding differences between the computed window
size and the content size, causing one row or column of black pixels on
the bottom or on the right.

This also avoids HiDPI scale issues, by computing the scaling manually.

This will also enable to draw items at their expected size on the screen
(unscaled).

Fixes #15 <https://github.com/Genymobile/scrcpy/issues/15>
2020-05-23 14:19:09 +02:00
Romain Vimont
a85848a541 Fix Windows Ctrl Handler declaration
The handler function signature must include the calling convention
declaration.

Ref: <https://stackoverflow.com/questions/61717439/why-calling-setconsolectrlhandler-triggers-a-warning>
2020-05-11 01:32:54 +02:00
Romain Vimont
28abd98f7f Properly handle Ctrl+C on Windows
By default, Ctrl+C just kills the process on Windows. This caused
corrupted video files on recording.

Handle Ctrl+C properly to clean up properly.

Fixes #818 <https://github.com/Genymobile/scrcpy/issues/818>
2020-05-08 14:54:33 +02:00
Romain Vimont
ead7ee4a03 Revert "Improve resizing workaround"
This reverts commit 92cb3a6661, which
broke the fullscreen/maximized restoration size on Windows.

Fixes #1346 <https://github.com/Genymobile/scrcpy/issues/1346>
2020-05-06 01:10:25 +02:00
Romain Vimont
c77024314d Add an option to keep the device awake
Add an option to prevent the device to sleep:

    scrcpy --stay-awake
    scrcpy -w

The initial state is restored on exit.

Fixes #631 <https://github.com/Genymobile/scrcpy/issues/631>
2020-05-02 02:14:25 +02:00
Romain Vimont
4668638ee1 Handle "show touches" on the device-side
Now that the server can access the Android settings and clean up
properly, handle the "show touches" option from the server.

The initial state is now correctly restored, even on device
disconnection.
2020-05-02 01:55:30 +02:00
Romain Vimont
92cb3a6661 Improve resizing workaround
Call the same method as when the event is received on the event loop, so
that the behavior is the same in both cases.
2020-04-24 21:36:25 +02:00
Romain Vimont
11a61b2cb3 Add option --no-mipmaps
Add an option to disable trilinear filtering even if mipmapping is
available.
2020-04-15 17:39:51 +02:00
Romain Vimont
8a9b20b27e Add --render-driver command-line option
Add an option to set a render driver hint (SDL_HINT_RENDER_DRIVER).
2020-04-15 17:39:51 +02:00
Romain Vimont
28c71c528f Add --rotation command-line option
In addition to Ctrl+Left and Ctrl+Right shortcuts, add a command-line
parameter to set the initial rotation.
2020-04-08 12:09:22 +02:00
e_vigurskiy
4150eedcdf Add display id parameter
Add --display command line parameter to specify a display id.

PR #1238 <https://github.com/Genymobile/scrcpy/pull/1238>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2020-04-02 21:02:52 +02:00
George Stamoulis
1982bc439b Add option to lock video orientation
PR #1151 <https://github.com/Genymobile/scrcpy/pull/1151>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2020-02-27 21:24:37 +01:00
Romain Vimont
4794ca8ae7 Use linear filtering
Anisotropic filtering makes no sense for scrcpy use case.

This (semantically) reverts 9e328ef98b.
2020-02-25 12:20:18 +01:00
Romain Vimont
dc7fcf3c7a Accept port range
Accept a range of ports to listen to, so that it does not fail if
another instance of scrcpy is currently starting.

The range can be passed via the command line:

    scrcpy -p 27183:27186
    scrcpy -p 27183  # implicitly 27183:27183, as before

The default is 27183:27199.

Closes #951 <https://github.com/Genymobile/scrcpy/issues/951>
2020-01-18 17:21:00 +01:00
Romain Vimont
8dc11a0286 Fix warnings on Windows
fix warnings reported with -Dwarning_level=2 on Windows.
2019-11-27 21:11:52 +01:00
Romain Vimont
31d9d56117 Fix warnings
Fix warnings reported with -Dwarning_level=2.
2019-11-26 09:10:41 +01:00
Romain Vimont
dfd0707a29 Move utilities to util/ 2019-11-24 11:53:23 +01:00
Romain Vimont
1d97d7213d Add option --max-fps
Add an option to limit the capture frame rate. It only works for devices
with Android >= 10.

Fixes <https://github.com/Genymobile/scrcpy/issues/488>
2019-11-17 22:10:39 +01:00
Diego Fernando Díaz A
59bc5bc1f5 Add option to disable window decoration
Add --window-borderless parameter.

Signed-off-by: Romain Vimont <rom@rom1v.com>
2019-11-15 18:59:40 +01:00
Romain Vimont
9fd7a80a89 Add option to specify the initial window size
Add --window-width and --window-height parameters.

If only one is provided, the other is computed so that the aspect ratio
is preserved.
2019-11-15 18:52:58 +01:00
Diego Fernando Díaz A
ce5635f28c Add option to specify the initial window position
Add --window-x and --window-y parameters.

Signed-off-by: Romain Vimont <rom@rom1v.com>
2019-11-15 18:50:49 +01:00
Romain Vimont
f6f2868868 Handle window events from screen.c
Only the screen knows what to do on window events.

This paves the way to handle more window events.
2019-11-11 15:02:26 +01:00
Romain Vimont
6996cbf5d3 Log device disconnection
If scrcpy closes due to socket disconnection, log a warning.
2019-11-09 21:17:03 +01:00
Romain Vimont
c916af0984 Add --prefer-text option
Expose an option to configure how key/text events are forwarded to the
Android device.

Enabling the option avoids issues when combining multiple keys to enter
special characters, but breaks the expected behavior of alpha keys in
games (typically WASD).

Fixes <https://github.com/Genymobile/scrcpy/issues/650>
2019-11-07 19:01:35 +01:00
Romain Vimont
b5a2d99bc2 Send touch events from the client
On SDL touch events, send control messages to the server.
2019-10-03 20:05:29 +02:00
Romain Vimont
1f8ba1ca79 Include config.h everywhere
Ref: <https://github.com/Genymobile/scrcpy/issues/829>

Suggested-by: Louis Kruger <louisk@gmail.com>
2019-09-29 22:39:53 +02:00
Romain Vimont
63af7fbafe Reduce latency by 1 frame
To packetize the H.264 raw stream, av_parser_parse2() (called by
av_read_frame()) knows that it has received a full frame only after it
has received some data for the next frame. As a consequence, the client
always waited until the next frame before sending the current frame to
the decoder!

On the device side, we know packets boundaries. To reduce latency,
make the device always transmit the "frame meta" to packetize the stream
manually (it was already implemented to send PTS, but only enabled on
recording).

On the client side, replace av_read_frame() by manual packetizing and
parsing.

<https://stackoverflow.com/questions/50682518/replacing-av-read-frame-to-reduce-delay>
<https://trac.ffmpeg.org/ticket/3354>
2019-07-31 01:55:32 +02:00
Romain Vimont
a90ccbdf3b Add option to change the push target
A drag & drop always pushed the file to /sdcard/.

Add an option to customize the target directory.

Fixes <https://github.com/Genymobile/scrcpy/issues/659>
2019-07-31 01:53:16 +02:00
beango1
8e65c10720 Add option --window-title
Add an option to set a custom window title.

Signed-off-by: Romain Vimont <rom@rom1v.com>
2019-06-24 19:58:00 +02:00
Romain Vimont
056e47e752 Replace "cannot" by "could not" 2019-06-23 20:52:03 +02:00
Romain Vimont
e2a272bf99 Improve framerate counting
The FPS counter was called only on new frames, so it could not print
values regularly, especially when there are very few FPS (when the
device surface does not change).

To the extreme, it was never able to display 0 fps.

Add a separate thread to print framerate every second.
2019-06-07 17:16:26 +02:00
Romain Vimont
eda44b6068 Fix controller cleanup
After commit bfb86ca2c2, the controller
was not stopped and destroyed on quit.
2019-06-07 00:03:21 +02:00
Romain Vimont
ebccb9f6cc Add runtime option to render expired frames
Replace the compilation flag SKIP_FRAMES by a runtime flag to force
rendering of expired frames. By default, the expired frames are skipped.
2019-06-05 21:39:42 +02:00
Romain Vimont
8e66b33000 Add option to turn device screen off
In addition to the shortcut (Ctrl+o) to turn the device screen off, add
a command-line argument to turn it off on start.
2019-06-05 00:55:46 +02:00
Romain Vimont
acc4dcd520 Disable server controller if --no-control
If --no-control is disabled, there is no need for a controller.

It also avoids to power on the device on start if control is disabled.
2019-06-05 00:25:57 +02:00
Romain Vimont
ca767ba364 Group server params in a struct
Starting the server requires more and more parameters. For clarity,
group them in a struct.
2019-06-05 00:25:57 +02:00
Romain Vimont
c8a6783494 Use positive options names internally
For clarity, store the flag resulting of the command-line options
--no-control and --no-display into "control" and "display".
2019-06-05 00:25:15 +02:00
Romain Vimont
9712cb8123 Do not minimize on focus loss
The default behavior seems annoying.

Fixes <https://github.com/Genymobile/scrcpy/issues/554>
2019-05-31 16:18:00 +02:00
Yu-Chen Lin
2a8a3e6ed5 Correct return value type in handle_event
handle_event return the type enum event_result not bool

Signed-off-by: Yu-Chen Lin <npes87184@gmail.com>
2019-05-31 20:57:06 +08:00
Romain Vimont
ec71a3f66a Use two sockets for video and control
The socket used the device-to-computer direction to stream the video and
the computer-to-device direction to send control events.

Some features, like copy-paste from device to computer, require to send
non-video data from the device to the computer.

To make them possible, use two sockets:
 - one for streaming the video from the device to the client;
 - one for control/events in both directions.
2019-05-30 22:35:41 +02:00
Romain Vimont
bfb86ca2c2 Simplify cleanup
The cleanup is not linear: for example, the server must be stopped and
its sockets must be shutdown after the stream and controller are stopped
(so that they don't continue processing garbage), but before they are
joined, to avoid a deadlock if they are blocked on a socket read.

Simplify the spaghetti-cleanup by keeping trace of initialization at
runtime.
2019-05-30 22:30:18 +02:00
Romain Vimont
5a431cdf9b Make server_connect_to() return a bool
The resulting socket is accessible from the server instance, there is no
need to return it.

This paves the way to use several sockets in parallel.
2019-05-30 22:30:18 +02:00
Romain Vimont
d2504f974c Fix indentation
Previous refactorings broke indentation.
2019-05-30 22:30:18 +02:00
Sebastian Krzyszkowiak
b941854c73 Disable X11 compositor bypass
Compositor bypass is meant for fullscreen games consuming lots of GPU
resources. For a light app that will usually be windowed, this only
causes unnecessary compositor suspends, especially visible (and
annoying) with complying window manager like KWin.

Signed-off-by: Romain Vimont <rom@rom1v.com>
2019-05-05 17:35:00 +02:00
Sebastian Krzyszkowiak
068253a3a2 Fix mouse focus clickthrough
Mouse focus clickthrough didn't work due to compat.h header not being
included in scrcpy.c.

Signed-off-by: Romain Vimont <rom@rom1v.com>
2019-05-05 17:28:25 +02:00
Romain Vimont
f7efafd846 Explicitly pass control flag to input manager
Replace the "global" control flag in the input_manager by a function
parameter to make explicit that the behavior depends whether
--no-control has been set.
2019-03-03 11:05:26 +01:00
Romain Vimont
6baed8a06f Do not init SDL video subsystem if no display
The SDL video subsystem is not necessary if we don't display the video.

Move the sdl_init_and_configure() function from screen.c to scrcpy.c,
because it is not only related to the screen display.
2019-03-03 01:41:35 +01:00
Romain Vimont
dfed1b250e Replace SDL types by C99 standard types
Scrcpy is a C11 project. Use the C99 standard types instead of the
SDL-specific types:

    SDL_bool -> bool
    SintXX   -> intXX_t
    UintXX   -> uintXX_t
2019-03-02 23:55:23 +01:00
Romain Vimont
8655ba7197 Add option to mirror in read-only
Add an option to disable device control: -n/--no-control.
2019-03-02 23:10:21 +01:00
Romain Vimont
163cd36ccc Rename -n/--no-window to -N/--no-display
The description of scrcpy is "Display and control your Android device".
We want an option to disable display, another one to disable control.

For naming consistency, name it --no-display.

Also change the shortname to -N, so that we can use -n for --no-control
later.
2019-03-02 22:46:46 +01:00
Romain Vimont
36191b7eec Avoid unnecessary call if display is disabled
If --no-window is passed, there is no need to register an event watcher.
2019-03-02 21:51:07 +01:00
Romain Vimont
33ccb1368f Extract event processing out of event_loop()
To avoid too many levels of nested blocks, move the event handling logic
in a separate function.
2019-03-02 21:51:07 +01:00
Romain Vimont
aeda583a2c Update code style
Limit source code to 80 chars, and declare functions return type and
modifiers on a separate line.

This allows to avoid very long lines, and all function names are
aligned.

(We do this on VLC, and I like it.)
2019-03-02 20:28:46 +01:00
Romain Vimont
89812e4eee Implement the --no-window flag
Disable decoder, screen (display), file_handler and controller when
--no-window is requested.

<https://github.com/Genymobile/scrcpy/pull/418>
2019-03-02 18:45:56 +01:00
Romain Vimont
e6e011baaf Add stream layer
The decoder initially read from the socket, decoded the video and sent
the decoded frames to the screen:

              +---------+      +----------+
  socket ---> | decoder | ---> |  screen  |
              +---------+      +----------+

The design was simple, but the decoder had several responsabilities.

Then we added the recording feature, so we added a recorder, which
reused the packets received from the socket managed by the decoder:

                                    +----------+
                               ---> |  screen  |
              +---------+     /     +----------+
  socket ---> | decoder | ----
              +---------+     \     +----------+
                               ---> | recorder |
                                    +----------+

This lack of separation of concerns now have concrete implications: we
could not (properly) disable the decoder/display to only record the
video.

Therefore, split the decoder to extract the stream:

                                    +----------+      +----------+
                               ---> | decoder  | ---> |  screen  |
              +---------+     /     +----------+      +----------+
  socket ---> | stream  | ----
              +---------+     \     +----------+
                               ---> | recorder |
                                    +----------+

This will allow to record the stream without decoding the video.
2019-03-02 18:45:45 +01:00
Romain Vimont
e7b7b083aa Store the recording request in a local bool
This avoids to test explicitly whether options->record_filename is NULL.
2019-03-02 18:21:20 +01:00
Romain Vimont
8aeb5c0e3c Fix cleanup order
The order of cleanup was not the reverse as the initialization order. As
a consequence, recorder_destroy() could theoretically be called even if
recorder_init() failed.
2019-03-02 18:13:11 +01:00
Romain Vimont
fff87095d9 Rename "frames" to "video_buffer"
It better describes the purpose of the structure.
2019-03-02 15:24:33 +01:00
Romain Vimont
0ed2373952 Support recording to MKV
Implement recording to Matroska files.

The format to use is determined by the option -F/--record-format if set,
or by the file extension (".mp4" or ".mkv").
2019-02-09 15:56:24 +01:00
Romain Vimont
ee3cba57a8 Forward FFmpeg logs
FFmpeg logs can be useful to understand the cause of issues.
2019-02-09 12:27:13 +01:00
Yu-Chen Lin
eca82e09c3 app: add always_on_top
It is very convenient when I play mobile game and watch video at the
same time.

Tested on Linux mint Cinnamon as well as Windows 10.

Signed-off-by: Yu-Chen Lin <npes87184@gmail.com>
2019-01-27 20:54:24 +08:00
Romain Vimont
345f8858d3 Send frame meta only if recording is enabled
The client needs the PTS for each frame only if recording is enabled.
Otherwise, the PTS are not necessary, and the protocol is more
straighforward.
2018-11-11 21:37:31 +01:00
Romain Vimont
22bf0c19d6 Rename --output-file to --record
To record the screen to a local file:

    scrcpy --record file.mp4
2018-11-11 21:37:31 +01:00
Romain Vimont
d0e090e1f9 Reenable custom SDL signal handlers
This partially reverts commit f00c6c5b13.

On Ctrl+C, we need to execute cleanup code. For instance, if recording
is enabled, we need to write MP4 file trailer on exit.

Custom SDL signal handlers were disabled because it leaded to process
hanging on Ctrl+C during network calls on initialization, but now it
seems to work correctly, the network calls return immediately on signal.
2018-11-11 21:37:31 +01:00
Romain Vimont
27686e9361 Add recorder
Implement recording in a separate "class".
2018-11-11 16:30:23 +01:00
Ivan Gorinov
d706c5df39 Enable video output file, with pts set by server 2018-11-11 16:30:23 +01:00
Philipp Sandhaus
af9808cf02 Add option to start in fullscreen
Signed-off-by: Romain Vimont <rom@rom1v.com>
2018-09-04 18:51:32 +02:00
Romain Vimont
536b31829a Separate multi-words filenames by '_'
Rename foobar.ext to foo_bar.ext.

<https://github.com/Genymobile/scrcpy/pull/226#discussion_r209454865>
2018-08-15 19:30:01 +02:00
npes87184
66f45f9dae Support drag&drop a file to transfer it to device
Signed-off-by: npes87184 <npes87184@gmail.com>
2018-08-15 17:12:10 +02:00
npes87184
aa97eed24b installer -> file_handler
Signed-off-by: npes87184 <npes87184@gmail.com>
2018-08-15 17:11:41 +02:00
Grief
cde0b3d248 Return non-zero value on connection loss
Make scrscpy to return 0 exit code only in case when the user closes its
app, otherwise, i.e. in case of connection loss, return 1.
2018-08-15 14:20:45 +02:00
Romain Vimont
caa9e30004 Add crop feature
Add an option to crop the screen on the server. This allows to mirror
only part of the device screen.
2018-08-09 19:12:27 +02:00
Adonis Najimi
e2a2973990 Drag and drop to install apk files from computer
<https://github.com/Genymobile/scrcpy/pull/133>
2018-05-28 20:45:54 +02:00
Romain Vimont
e3d0a59c80 Fix proc_show_touches warning
In practice, proc_show_touches may not be used uninitialized, since it
checks the flag options->show_touches, but the compiler can't know that,
so initialize it to avoid the warning.
2018-05-28 20:21:50 +02:00
Romain Vimont
57eaf05289 Improve startup time when show_touches is enabled
Enabling "show touches" involves the execution of an adb command, which
takes some time.

In order to parallelize, execute the command as soon as possible, but
reap the process only once everything is initialized.
2018-03-25 16:39:36 +02:00
Romain Vimont
dd2a5c1ecf Disable "show touches" once window is closed
If --show-touches is set, then the option must be disabled on quit.

Since it executes an adb command, it takes some time, so close the
window beforehand so that the close window button does not seem
unresponsive.
2018-03-25 16:03:02 +02:00
Romain Vimont
66ec252893 Add an option to enable "show touches"
Add -t/--show-touches option to show physical touches while scrcpy is
running.

See <https://github.com/Genymobile/scrcpy/issues/96>.
2018-03-25 15:43:27 +02:00
Romain Vimont
b13d25b9f4 Group scrcpy options into a struct
The scrcpy() function accepts as many parameters as there are options.

To simplify, group all options in a separate struct.
2018-03-25 15:16:29 +02:00
Romain Vimont
f00c6c5b13 Disable custom SDL signal handlers
Request SDL not to replace the SIGINT and SIGTERM handlers, so that the
process is immediately terminated on Ctrl+C.

This avoids process hanging on Ctrl+C during network calls on
initialization.

Some of them accepted a timeout, but it was not used since
commit 9b056f5091 anymore.
2018-03-21 21:43:12 +01:00
Romain Vimont
080df5eb5d Fix switch/case code style
For readability and consistency, indent case statatements, and remove
unnecessary additional blocks.
2018-03-15 16:00:40 +01:00
Romain Vimont
8a3c6a3ae7 Remove useless argument
Do not pass any data to the event watcher, it is unused.
2018-03-14 09:32:05 +01:00
Romain Vimont
0b1e59186f Workaround continuous resizing on Windows/MacOS
On Windows and MacOS, resizing blocks the event loop, so resizing events
are not triggered:
 - <https://bugzilla.libsdl.org/show_bug.cgi?id=2077>
 - <https://stackoverflow.com/a/40693139/1987178>

As a workaround, register an event watcher to render the screen from
another thread.

Since the whole event loop is blocked during resizing, the screen
content is not refreshed (on Windows and MacOS) until resizing ends.
2018-03-13 22:48:04 +01:00
Romain Vimont
2b3ed5bcdb Store serial in server instance
The serial is needed for many server actions, but this is an
implementation detail, so the caller should not have to provide it on
every call.

Instead, store the serial in the server instance on server_start().

This paves the way to implement the "adb forward" fallback properly.
2018-03-12 14:10:32 +01:00
Romain Vimont
ad6209f6ff Terminate the device process gracefully
Call shutdown() on the device socket to make the device process finish
its execution quickly and gracefully, without killing it.
2018-02-16 11:47:42 +01:00
Romain Vimont
9b056f5091 Replace SDL_net by custom implementation
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.
2018-02-16 00:56:58 +01:00
Romain Vimont
d977202224 Add Ctrl+i shortcut to enable/disable FPS counter
Disable FPS counter on start, and use Ctrl+i to enable/disable it.
2018-02-15 12:24:16 +01:00
Romain Vimont
000ced9ba8 Refactor screencontrol to inputmanager
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.
2018-02-15 12:07:47 +01:00
Romain Vimont
38e6682875 Add FPS counter
Remove frame counter from scrcpy.c and add a new FPS counter, logging as
INFO the measured frame rate every second (on new frame).
2018-02-15 11:22:48 +01:00
Romain Vimont
3ed80a1fac Define macros wrappers for logs
Use macros to wrap SDL_Log* functions with the "application" category.
2018-02-13 10:10:18 +01:00
Romain Vimont
eb09fefd43 Timeout the server socket connection
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).
2018-02-09 16:21:10 +01:00
Romain Vimont
90a46b4c45 Improve startup time
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.
2018-02-09 16:19:50 +01:00
Romain Vimont
523097eadf Provide decoder_init()
Expose an initializer so that the caller does not have to guess what
fields must be initialized.
2018-02-09 13:30:49 +01:00
Romain Vimont
4662198261 Do not release TCP sockets while still in use
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().
2018-02-09 12:59:36 +01:00
Romain Vimont
fe21d9dfb5 Move frame updating to screen.c
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.
2018-02-09 11:14:47 +01:00
Romain Vimont
127e56780a Fix deadlock on exit if SKIP_FRAMES disabled
On exit, the renderer will not consume frames anymore, so signal the
condition variable to wake up the decoder.
2018-02-09 09:41:05 +01:00
Romain Vimont
629c296207 Move frame swapping logic to frame.c
Expose frames_offer_decoded_frame() and frames_consume_rendered_frame()
so that callers are not exposed to frame swapping (between the decoding
and rendering frames) details.
2018-02-08 20:57:29 +01:00
Romain Vimont
0d7f050389 Unlock mutex on screen update failure
The mutex was not unlocked on all code paths.
2018-02-08 18:39:38 +01:00
Romain Vimont
e8dfb723af Move control-related code to screencontrol.c
Move the code handling user input from scrcpy.c to a separate file,
screencontrol.c.
2018-02-08 18:14:50 +01:00
Romain Vimont
e1749a0c09 Remove the "adb reverse" tunnel immediately
As soon as we accepted a connection, we can remove the "adb reverse"
tunnel.
2018-02-08 17:40:09 +01:00
Romain Vimont
3b06e7d500 Move device-related code to device.c
Move the code to read the initial device info from scrcpy.c to a
separate file, device.c.
2018-02-08 17:40:09 +01:00
Romain Vimont
28c5cc030b Move server-related code to server.c
The file server.c already existed, but exposed a low-level API. Make it
higher-level, so that scrcpy.c does not handle server details directly.
2018-02-08 17:40:09 +01:00
Romain Vimont
6c578b5caa Move screen-related code to screen.c
The file scrcpy.c contains too many different things in addition to the
main logic, so move the screen code to a separate file, screen.c.
2018-02-08 15:43:28 +01:00
Romain Vimont
ffae15e36a Rename control to controller
The struct decoder is defined in decoder.h.

For naming consistency, define the struct controller in controller.h.
2018-02-08 13:26:01 +01:00
Romain Vimont
7b7fd77134 Add missing static
Some functions in scrcpy.c are not used outside the file, so declare
them static.
2018-02-08 09:08:55 +01:00
Romain Vimont
f39de46a39 Add delay before stopping server
Let some time to print any exception trace before killing it.
2018-02-07 15:41:59 +01:00
Romain Vimont
cb1428223f Log user request to quit
Log at debug level user requests to quit.
2018-02-07 15:41:59 +01:00
Romain Vimont
8d30d40b79 Make SKIP_FRAMES a compilation flag
The skip_frames flag was a non-configurable runtime flag. Since it is
not exposed to the user, there is no need for a (possible) runtime cost.

For testing purpose, we still want it to be configurable, so make it a
compilation flag.
2018-02-07 15:40:24 +01:00
Romain Vimont
71c2bfdd22 Parse XPM without SDL_image
We encounter some problems with SDL2_image on MSYS2 (Windows), so
implement our own XPM parsing which does not depend on SDL_image.

The input XPM is considered safe (it's in our source repo), so do not
check XPM format errors. This implies that read_xpm() is not safe to
call on any unsafe input.

Although less straightforward, use SDL_CreateRGBSurfaceFrom() instead of
SDL_CreateRGBSurfaceWithFormatFrom() because it is available with SDL
versions older than 2.0.5.
2018-02-05 19:24:33 +01:00
Romain Vimont
f22d4decca Enable mouse focus clickthrough only if available
The hint SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH appeared in SDL 2.0.5. Ignore
it if the SDL version is older.
2018-02-05 16:15:52 +01:00
Romain Vimont
52c89c7afb Add window icon
Add a bugdroid icon loaded from an XPM.
2018-02-05 14:46:00 +01:00
Romain Vimont
5eb91a4ca7 Fix scrcpy() return value
The scrcpy() function returns a SDL_bool to indicate its success, but
was initialized to 0 (SDL_FALSE) instead of SDL_TRUE.
2018-02-04 12:39:17 +01:00
Romain Vimont
69a359c7f4 Refactor actions calls
The purpose of handle_shortcut() was to group all actions together,
whether they are initiated from a text input event or a keycode event.

However, it did not handle the case where it was initiated from a mouse
event (a right-click must turn the screen on), since the action was
identified by the shortcut char.

Instead, expose one function per action, to be called directly from
where the event is handled.
2018-02-02 15:23:04 +01:00
Romain Vimont
d73dee9833 fixup! Handle all shortcuts in the same function 2018-02-02 15:17:03 +01:00
Romain Vimont
a139509f11 Turn screen on on right-click
The right-click is almost useless on Android, so use it to turn the
screen on.

Add a new control event type (command) to request the server to turn the
screen on.
2018-02-02 14:56:03 +01:00
Romain Vimont
deba69d022 Handle all shortcuts in the same function
Shortcuts are sometimes initiated from a keycode event, and sometimes
from a text input event.

Move the handling to a unique function.
2018-02-02 12:01:38 +01:00
Romain Vimont
7f6a565401 Extract shortcut actions to separate functions
To simplify event handling code, move all actions to separate functions.
2018-02-02 11:52:19 +01:00
Romain Vimont
f8ad007a28 Move switch fullscreen logs
Logs were printed by the caller of switch_fullscreen(). Move them inside
the function to simplify event handling code.
2018-02-02 11:48:05 +01:00
Romain Vimont
6fe7b84629 Add shortcuts for physical keys
Add shortcuts for HOME, BACK, APPS, POWER, VOLUME_UP and VOLUME_DOWN.
2018-02-02 11:39:25 +01:00
Romain Vimont
ca44585f96 Do not send simple mouse move events
Moving the mouse without any button pressed has no effect on Android.
Therefore, do not even send these very frequent events.
2018-02-02 09:26:25 +01:00
Romain Vimont
79b28eb68f Enable mouse focus clickthrough
Consider a click to gain focus as a click on the device.
2018-02-01 20:52:44 +01:00
Romain Vimont
6b546a87ab Add bit-rate command-line option
Add a command-line option (-b/--bit-rate) to customize the video
bit-rate.
2018-02-01 17:11:40 +01:00
Romain Vimont
2683fa20ed Add debug log for shortcuts
Add a debug log for every succeeded shortcut action.
2018-02-01 17:11:40 +01:00
Romain Vimont
274e1ac9ec Fix rotation bug in fullscreen mode on X11
On rotation, scrcpy resize the window to match the new rotation.
However, in fullscreen mode, setting the window size does not change the
windowed size on X11, so the behavior is incorrect.

To avoid the problem, apply the resize only after fullscreen is
disabled.
2018-02-01 17:11:40 +01:00
Romain Vimont
ee93f3f23a Rename maximum_size to max_size
The long option is --max-size, so for consistency, adapt the code
accordingly.
2018-02-01 17:11:40 +01:00
Romain Vimont
60b2f2ca64 Indent switch blocks content
For readability, indent "case" in switch blocks.

Replace:

    switch (x) {
    case 1:
        // ...
    case 2:
        // ...
    case 3: { // a local scope block
        int i = 42;
        // ...
    }
    }

By:

    switch (x) {
        case 1:
            // ...
        case 2:
            // ...
        case 3: { // a local scope block
            int i = 42;
            // ...
        }
    }
2018-02-01 11:44:20 +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
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
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
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
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
54d9148a36 Initial commit
Start a new clean history from here.
2017-12-12 15:25:15 +01:00