On initial connection, scrcpy sent some device metadata:
- the device name (to be used as window title)
- the initial video size (before any frame or even SPS/PPS)
But it is better to provide the initial video size as part as the video
stream, so that it can be demuxed and exposed via AVCodecContext to
sinks.
This avoids to pass an explicit "initial frame size" for the screen, the
recorder and the v4l2 sink.
If no bit-rate is passed, let the server use the default value (8Mbps).
This avoids to define a default value on both sides, and to pass the
default bit-rate as an argument when starting the server.
PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
When audio is enabled, open a new socket to send the audio stream from
the device to the client.
PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
Audio will be enabled by default (when supported). Add an option to
disable it.
PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
Running scrcpy --tcpip on a device already connected via TCP/IP did not
initialize server->serial.
As a consequence, in debug mode, an assertion failed:
scrcpy: ../app/src/server.c:770: run_server: Assertion
`server->serial' failed.
In release mode, scrcpy failed with this error:
adb: -s requires an argument
For the initial connection between the device and the computer, an adb
tunnel is established (with "adb reverse" or "adb forward").
The device-side of the tunnel is a local socket having the hard-coded
name "scrcpy". This may cause issues when several scrcpy instances are
started in a few seconds for the same device, since they will try to
bind the same name.
To avoid conflicts, make the client generate a random UID, and append
this UID to the local socket name ("scrcpy_01234567").
If the current adb port is not 5555 (typically 0 because it is not in
TCP/IP mode), --tcpip automatically executes (among other commands):
adb tcpip 5555
In case adb was already listening on another port, this command forced
to listen on 5555, and the connection should still succeed.
But this reconfiguration might be inconvenient for the user. If adb is
already in TCP/IP mode, use the current enabled port without
reconfiguration.
Fixes#3591 <https://github.com/Genymobile/scrcpy/issues/3591>
If several devices are connected (as listed by `adb devices`), it was
necessary to provide the explicit serial via -s/--serial.
If only one device is connected via USB (respectively, via TCP/IP), it
might be convenient to select it automatically. For this purpose, two
new options are introduced:
- -d/--select-usb: select the single device connected over USB
- -e/--select-tcpip: select the single device connected over TCP/IP
PR #3005 <https://github.com/Genymobile/scrcpy/pull/3005>
Currently, a device is selected either from a specific serial, or if it
is the only one connected.
In order to support selecting the only device connected via USB or via
TCP/IP separately, introduce a new selection structure.
PR #3005 <https://github.com/Genymobile/scrcpy/pull/3005>
This does nothing if the adb daemon is already started, but allows to
print any output/errors to the console.
Otherwise, the daemon starting would occur during `adb devices`, which
does not output to the console because the result is parsed.
PR #3005 <https://github.com/Genymobile/scrcpy/pull/3005>
Before starting the server, the actual device serial (possibly its
ip:port if it's over TCP/IP) must be known.
A serial might be requested via -s/--serial (stored in the
sc_server_params), but the actual serial may change afterwards:
- if none is provided, then it is retrieved with "adb get-serialno";
- if --tcpip is requested, then the final serial will be the target
ip:port.
The requested serial was overwritten by the actual serial in the
sc_server_params struct, which was a bit hacky.
Instead, store a separate serial field in sc_server (and rename the one
from sc_server_params to "req_serial" to avoid confusion).
Now that providing a serial is mandatory for adb commands where it is
relevant, the whole argv array may be built statically, without
allocations at runtime.
The server needs to interrupt the sockets on stop, but it must not close
them while other threads may attempt to read from or write to them.
In particular, the video_socket is read by the stream thread, and the
control_socket is written by the controller and read by receiver.
Therefore, close the socket only on sc_server_destroy(), which is called
after all other threads are joined.
Reported by TSAN on close:
WARNING: ThreadSanitizer: data race (pid=3287612)
Write of size 8 at 0x7ba000000080 by thread T1:
#0 close ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1690 (libtsan.so.0+0x359d8)
#1 net_close ../app/src/util/net.c:280 (scrcpy+0x23643)
#2 run_server ../app/src/server.c:772 (scrcpy+0x20047)
#3 <null> <null> (libSDL2-2.0.so.0+0x905a0)
Previous read of size 8 at 0x7ba000000080 by thread T16:
#0 recv ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:6603 (libtsan.so.0+0x4f4a6)
#1 net_recv_all ../app/src/util/net.c:228 (scrcpy+0x234a9)
#2 stream_recv_packet ../app/src/stream.c:33 (scrcpy+0x2045c)
#3 run_stream ../app/src/stream.c:228 (scrcpy+0x21169)
#4 <null> <null> (libSDL2-2.0.so.0+0x905a0)
Refs ddb9396743
Prefix the name of threads by "scrcpy-". This improves readability in
the output of `top -H` for example.
Limit the thread names to 16 bytes, because it is limited on some
platforms.
The sockets were never interrupted or closed by the client since recent
changes to run the server from a dedicated thread (see commit
0426708544).
As a side effect, the server could never terminate properly (it was
waiting on socket blocking calls), so it was always killed by the client
after the WATCHDOG_DELAY.
Interrupt the sockets on stop to give the servera chance to terminate
property, then close them.
If --no-control is enabled, then it is not necessary to create a second
communication socket between the client and the server.
This also facilitates the use of the server alone (without the client)
to receive only the raw video stream.