The size, point and position structs were defined in common.h. Move them
to coords.h so that common.h could be used for generic code to be
included in all source files.
Let the server terminate properly once all the sockets are closed.
If it does not terminate (this can happen if the device is asleep), then
kill it.
Note: since the server process termination is detected by a flag set
after waitpid() returns, there is a small chance that the process
terminates (and the PID assigned to a new process) before the flag is
set but before the kill() call. This race condition already existed
before this commit.
Fixes#1992 <https://github.com/Genymobile/scrcpy/issues/1992>
The header scrcpy.h is intended to be the "public" API. It should not
depend on other internal headers.
Therefore, declare all required structs in this header and adapt
internal code.
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.
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
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.
The server may die before connecting to the client. In that case, the
client was blocked indefinitely (until Ctrl+C) on accept().
To avoid the problem, close the server socket once the server process is
dead.
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>
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>
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.
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.)
To clean up the device, the client executed "adb shell rm" once the
server was guaranteed to be started (after the connection succeeded).
This implied to track whether the installation state, and failed if an
additional tunnel was used in "forward" mode:
<https://github.com/Genymobile/scrcpy/issues/386#issuecomment-453936034>
Instead, make the server unlink itself on start.
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.
"adb reverse" currently does not work over tcpip (i.e. on a device
connected by "adb connect"):
<https://issuetracker.google.com/issues/37066218>
To work around the problem, if the call to "adb reverse" fails, then
fallback to "adb forward", and reverse the client/server roles.
Keep the "adb reverse" mode as the default because it does not involve
connection retries: when using "adb forward", the client must try to
connect successively until the server listens.
Due to the tunnel, every connect() will succeed, so the client must
attempt to read() to detect a connection failure. For this purpose, when
using the "adb forward" mode, the server initially writes a dummy byte,
read by the client.
Fixes <https://github.com/Genymobile/scrcpy/issues/5>.
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.
The server is copied to /data/local/tmp/scrcpy-server.jar and executed
on the device.
As soon as we are connected, we can unlink (rm) it from /data/local/tmp,
to keep the device clean.
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.
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().