Commit graph

950 commits

Author SHA1 Message Date
Romain Vimont
ac23bec144 Expose socket interruption
On Linux, socket functions are unblocked by shutdown(), but on Windows
they are unblocked by closesocket().

Expose net_interrupt() and net_close() to abstract these differences:
 - net_interrupt() calls shutdown() on Linux and closesocket() on
   Windows (if not already called);
 - net_close() calls close() on Linux and closesocket() on Windows (if
   not already called).

This simplifies the server code, and prevents a data race on close
(reported by TSAN) on Linux (but does not fix it on Windows):

    WARNING: ThreadSanitizer: data race (pid=836124)
      Write of size 8 at 0x7ba0000000d0 by main thread:
        #0 close ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1690 (libtsan.so.0+0x359d8)
        #1 net_close ../app/src/util/net.c:211 (scrcpy+0x1c76b)
        #2 close_socket ../app/src/server.c:330 (scrcpy+0x19442)
        #3 server_stop ../app/src/server.c:522 (scrcpy+0x19e33)
        #4 scrcpy ../app/src/scrcpy.c:532 (scrcpy+0x156fc)
        #5 main ../app/src/main.c:92 (scrcpy+0x622a)

      Previous read of size 8 at 0x7ba0000000d0 by thread T6:
        #0 recv ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:6603 (libtsan.so.0+0x4f4a6)
        #1 net_recv ../app/src/util/net.c:167 (scrcpy+0x1c5a7)
        #2 run_receiver ../app/src/receiver.c:76 (scrcpy+0x12819)
        #3 <null> <null> (libSDL2-2.0.so.0+0x84f40)
2021-10-27 18:41:58 +02:00
Romain Vimont
e5ea13770b Add socket wrapper
This paves the way to store an additional "closed" flag on Windows
to interrupt and close properly.
2021-10-26 22:49:57 +02:00
Romain Vimont
3eac212af1 Use net_send() from net_send_all()
This will make net_send_all() continue to work even if net_send()
behavior is changed.
2021-10-26 22:49:45 +02:00
Romain Vimont
3adff37c2d Use sc_ prefix for sockets
Rename:
 - socket_t to sc_socket
 - INVALID_SOCKET to SC_INVALID_SOCKET
2021-10-26 22:49:45 +02:00
Romain Vimont
eb6afe7669 Move net_init() and net_cleanup() upwards
These two functions are global, define them at the top of the
implementation file. This is consistent with the header file.
2021-10-26 22:49:45 +02:00
Romain Vimont
e4163321f0 Delay HID events on Ctrl+v
When Ctrl+v is pressed, a control is sent to the device to set the
device clipboard before injecting Ctrl+v.

With the InputManager method, it is guaranteed that the device
synchronization is executed before handling Ctrl+v, since the commands
are executed on the device in sequence.

However, HID are injected from the computer, so there is no such
guarantee. As a consequence, on Android, Ctrl+v triggers a paste with
the old clipboard content.

To workaround the issue, wait a bit (2 milliseconds) from the AOA
thread before injecting the event, to leave enough time for the
clipboard to be set before injecting Ctrl+v.
2021-10-26 21:30:04 +02:00
Romain Vimont
c96874b257 Synchronize HID keyboard state on first event
When an AOA HID keyboard is registered, CAPSLOCK and NUMLOCK are both
disabled, regardless of the state of the computer keyboard.

To synchronize the state, on first key event, inject CAPSLOCK and/or
NUMLOCK if necessary.
2021-10-26 21:30:04 +02:00
Romain Vimont
511356710d Retrieve device serial for AOA
The serial is necessary to find the correct Android device for AOA.

If it is not explicitly provided by the user via -s, then execute "adb
getserialno" to retrieve it.
2021-10-26 21:30:04 +02:00
Romain Vimont
d55015e4cf Expose function to get the device serial
Expose adb_get_serialno() to retrieve the device serial via the command
"adb getserialno".
2021-10-26 21:30:04 +02:00
Romain Vimont
0681480809 Add read_pipe_all()
Add a convenience function to read from a pipe until all requested data
has been read.
2021-10-26 21:30:04 +02:00
Romain Vimont
96b18dabaa Expose adb execution with redirection
Expose the redirection feature to the adb API.
2021-10-26 21:30:04 +02:00
Romain Vimont
eaf4afaad9 Add command execution with redirection
Expose command execution with pipes to stdin, stdout and stderr.

This will allow to read the result of adb commands.
2021-10-26 21:30:04 +02:00
Alynx Zhou
207082977a Add support for USB HID keyboard over AOAv2
This provides a better input experience, by simulating a physical
keyboard. It converts SDL keyboard events to proper HID events, and send
them over AOAv2.

This is a rewriting and bugfix of the origin code from @amosbird:
<https://github.com/Genymobile/scrcpy/issues/279#issuecomment-453819354>

The feature is enabled the command line option -K or --hid-keyboard,
and is only available on Linux, over USB.

Refs <https://source.android.com/devices/accessories/aoa2#hid-support>
Refs <https://www.usb.org/sites/default/files/hid1_11.pdf>

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

Signed-off-by: Romain Vimont <rom@rom1v.com>
2021-10-26 21:30:04 +02:00
Romain Vimont
f7d1efdf1d Extract mouse processor trait
Mainly for consistency with the keyboard processor trait.

This could allow to provide alternative mouse processors.
2021-10-26 21:30:04 +02:00
Romain Vimont
bcf5a9750f Extract keyboard processor trait
This will allow to provide alternative key processors.
2021-10-26 21:30:04 +02:00
Romain Vimont
056d36ce4a Fix trait header guards 2021-10-26 21:30:04 +02:00
Romain Vimont
1e340caf76 Remove legacy scrcpy icon
Remove the old icon in XPM format and the code to load it.
2021-10-25 18:08:37 +02:00
Romain Vimont
6004f0b6b0 Use a new scrcpy icon
Use the new icon designed by @varlesh:
<https://github.com/Genymobile/scrcpy/pull/1987#issuecomment-949684080>

Load it from a PNG file (SDL only supports bitmap icons).
2021-10-25 18:08:37 +02:00
Romain Vimont
12ed2f2402 Add support for palette icon formats
To support more icon formats.
2021-10-25 18:08:37 +02:00
Romain Vimont
0e4564da03 Add icon loader
Add helper to load icons from image files via FFmpeg.
2021-10-25 18:08:37 +02:00
Romain Vimont
156d958e77 Move common instruction out of ifdef
Both ifdef-branches return server_path.
2021-10-25 18:08:31 +02:00
Romain Vimont
7229e3cce0 Extract util function to build a local file path
Finding a local file in the scrcpy directory may be useful for files
other than scrcpy-server in the future.
2021-10-25 16:29:43 +02:00
Romain Vimont
a7e41b0f85 Fix code style 2021-10-21 18:36:34 +02:00
zhongkaizhu
46d3e35c30 Fix "Could not find v4l2 muxer"
The AVOutputFormat name is a comma-separated list. In theory, possible
names for V4L2 are:

    - "video4linux2,v4l2"
    - "v4l2,video4linux2"
    - "v4l2"
    - "video4linux2"

To find the muxer in all cases, we must request exactly one muxer name
at a time.

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

Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2021-10-21 16:26:48 +02:00
Romain Vimont
07d75eb336 Simplify net_send_all()
There is no need to declare the variable before the loop.
2021-10-17 16:21:37 +02:00
Romain Vimont
31131039bb Add missing includes
Refs #2616 <https://github.com/Genymobile/scrcpy/issues/2616>
2021-09-20 18:27:37 +02:00
Romain Vimont
1d1c9f36f4 Retrieve correct error messages on Windows
For sockets functions, Windows does not store error codes in errno, so
perror() does not print any error. Use WSAGetLastError() instead.

Refs #2624 <https://github.com/Genymobile/scrcpy/issues/2624>
2021-09-09 23:03:35 +02:00
Romain Vimont
4d6dd9d281 Compute scrcpy directory manually
The function dirname() does not work correctly everywhere with non-ASCII
characters.

Fixes #2619 <https://github.com/Genymobile/scrcpy/issues/2619>
2021-09-09 12:51:18 +02:00
a1346054
b5e98db635 Fix typo in manpage
PR #2606 <https://github.com/Genymobile/scrcpy/pull/2606>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2021-09-07 21:41:40 +02:00
Romain Vimont
3761f56c28 Declare callbacks static
It was a typo, "static" was missing.
2021-08-26 12:26:44 +02:00
Romain Vimont
f78608ab29 Fix type for assignment
The functions net_send_all() and net_recv_all() return ssize_t, not int.
2021-07-15 18:16:56 +02:00
Romain Vimont
6f03022646 Fix net_send_all()
On partial writes, the final result was the number of bytes written by
the last send() rather than the total.
2021-07-15 18:16:26 +02:00
Romain Vimont
daf90d33d5 Fix code style
Make the code fit into 80 columns.
2021-07-15 18:07:39 +02:00
Romain Vimont
0ae10f2b39 Improve slope estimation on start
The first frames are typically received and decoded with more delay than
the others, causing a wrong slope estimation on start.

To compensate, assume an initial slope of 1, then progressively use the
estimated slope.
2021-07-14 14:54:22 +02:00
Romain Vimont
4c4d02295c Add buffering debugging tools
Output buffering and clock logs by disabling a compilation flag.
2021-07-14 14:54:22 +02:00
Romain Vimont
2f03141e9f Add clock tests
The clock rolling sum is not trivial. Test it.
2021-07-14 14:54:22 +02:00
Romain Vimont
3397720330 Add buffering command line options
Add --display-buffer and --v4l2-buffer options to configure buffering
time.
2021-07-14 14:54:22 +02:00
Romain Vimont
79278961b9 Implement buffering
To minimize latency (at the cost of jitter), scrcpy always displays a
frame as soon as it available, without waiting.

However, when recording (--record), it still writes the captured
timestamps to the output file, so that the recorded file can be played
correctly without jitter.

Some real-time use cases might benefit from adding a small latency to
compensate for jitter too. For example, few tens of seconds of latency
for live-streaming are not important, but jitter is noticeable.

Therefore, implement a buffering mechanism (disabled by default) to add
a configurable latency delay.

PR #2417 <https://github.com/Genymobile/scrcpy/issues/2417>
2021-07-14 14:27:33 +02:00
Romain Vimont
408a301201 Notify new frames via callbacks
Currently, a frame is available to the consumer as soon as it is pushed
by the producer (which can detect if the previous frame is skipped).

Notify the new frames (and frame skipped) via callbacks instead.

This paves the way to add (optional) buffering, which will introduce a
delay between the time when the frame is produced and the time it is
available to be consumed.
2021-07-14 14:22:32 +02:00
Romain Vimont
4d8bcfc68a Extract current video_buffer to frame_buffer
The current video buffer only stores one pending frame.

In order to add a new buffering feature, move this part to a separate
"frame buffer". Keep the video_buffer, which currently delegates all its
calls to the frame_buffer.
2021-07-14 14:22:32 +02:00
Romain Vimont
336248df08 Rename video_buffer to sc_video_buffer
Add a scrcpy-specific prefix.
2021-07-14 14:22:32 +02:00
Romain Vimont
28bce48d47 Relax v4l2_sink lock constraints
To fix a data race, commit 5caeab5f6d
called video_buffer_push() and video_buffer_consume() under the
v4l2_sink lock.

Instead, use the previous_skipped indication (initialized with video
buffer locked) to lock only for protecting the has_frame flag.

This enables the possibility for the video_buffer to notify new frames
via callbacks without lock inversion issues.
2021-07-14 14:22:32 +02:00
Romain Vimont
32e692d5d2 Replace delay by deadline in timedwait()
The function sc_cond_timedwait() accepted a parameter representing the
max duration to wait, because it internally uses SDL_CondWaitTimeout().

Instead, accept a deadline, to be consistent with
pthread_cond_timedwait().
2021-07-14 14:22:32 +02:00
Romain Vimont
ec871dd3f5 Wrap tick API
This avoids to use the SDL timer API directly, and will allow to handle
generic ticks (possibly negative).
2021-07-14 14:22:32 +02:00
Romain Vimont
5524f378c8 Add missing error log
Log video buffer initialization failure in v4l2_sink.
2021-07-14 00:39:35 +02:00
Romain Vimont
4ed3aa3604 Move include fps_counter
The fps_counter is not used from video_buffer.
2021-07-14 00:35:10 +02:00
Romain Vimont
40cea1f677 Remove obsolete comment
Commit 2a94a2b119 removed video_buffer
callbacks, the comment is now meaningless.
2021-07-14 00:35:10 +02:00
Romain Vimont
099cba07f0 Rename queue to sc_queue
Add a scrcpy-specific prefix.
2021-07-14 00:35:10 +02:00
Romain Vimont
af8a21ed7c Fix manpage formatting 2021-07-06 18:33:04 +02:00
Romain Vimont
5938e862a1 Fix --lock-video-orientation syntax in help
Commit f76fe2c0d4 fixed README and tests.

Fix command line help and manpage.
2021-07-06 18:32:40 +02:00
Romain Vimont
e9096e3e34 Remove unnecessary calls to av_packet_unref()
av_packet_free() already calls av_packet_unref().
2021-07-04 12:19:52 +02:00
Romain Vimont
5caeab5f6d Fix v4l2 data race
The v4l2_sink implementation directly read the internal video_buffer
field "pending_frame_consumed", which is protected by the internal
video_buffer mutex. But this mutex was not locked, so reads were racy.

Lock using the v4l2_sink mutex in addition, and use a separate field to
avoid depending on the video_buffer internal data.
2021-06-26 16:03:52 +02:00
Romain Vimont
33fbdc86c7 Initialize fields before starting a thread
To avoid data races.

Reported by TSAN.
2021-06-26 16:03:34 +02:00
Romain Vimont
f33d37976c Fix assertion race condition in debug mode
Commit 21d206f360 added mutex assertions.

However, the "locker" variable to trace the locker thread id was read
and written by several threads without any protection, so it was racy.

Reported by TSAN.
2021-06-26 15:31:50 +02:00
Romain Vimont
7dca5078e7 Initialize controller even if there is no display
The options --no-display and --no-control are independent.

The controller was not initialized when no display was requested,
because it was assumed that no control could occur without display. But
that's not true (anymore): for example, it is possible to pass
--turn-screen-off.

Fixes #2426 <https://github.com/Genymobile/scrcpy/issues/2426>
2021-06-25 21:48:07 +02:00
Wirtos_new
a9d9cbf8b5 Replace VLA by dynamic allocation
And increase the command buffer size.

Refs #1358 <https://github.com/Genymobile/scrcpy/issues/1358#issuecomment-862989748>
PR #2405 <https://github.com/Genymobile/scrcpy/pull/2405>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2021-06-20 21:16:42 +02:00
Wirtos_new
fda32928c1 Rename cmd to argv
This is more explicit.

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

Signed-off-by: Romain Vimont <rom@rom1v.com>
2021-06-20 21:16:42 +02:00
Romain Vimont
710e80aa0d Return build_cmd() success via a boolean
For consistency with other functions in the codebase.
2021-06-20 21:16:42 +02:00
Romain Vimont
77e96d745b Suggest --record-format instead of -F on error
The short option -F has been deprecated by
ff061b4f30. On error, suggest the long
option --record-format instead.
2021-06-20 21:16:03 +02:00
Romain Vimont
1c95043478 Attempt to log message only in verbose mode
If the log level is not verbose, there is no need to attempt to log
control messages at all.
2021-06-20 16:44:59 +02:00
Romain Vimont
488991116b Expose function to get the current log level
This will allow to avoid unnecessary processing for creating logs which
will be discarded anyway.
2021-06-20 16:04:18 +02:00
Romain Vimont
5c95d18beb Move log level conversion to log API 2021-06-20 16:04:18 +02:00
Romain Vimont
1039f9b531 Workaround PRIu64 on Windows
On Windows, PRIu64 is defined to "llu", which is not supported:

    error: unknown conversion type character 'l' in format
2021-06-20 16:04:18 +02:00
Marti Raudsepp
19ca02cd8f Log control messages in verbose mode
PR #2371 <https://github.com/Genymobile/scrcpy/pull/2371>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2021-06-20 16:03:52 +02:00
Marti Raudsepp
937fa704a6 Add --verbosity=verbose log level
PR #2371 <https://github.com/Genymobile/scrcpy/pull/2371>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2021-06-20 12:34:19 +02:00
Romain Vimont
7db0189f23 Forward mouse motion only on main clicks
Mouse motion events were forwarded as soon as any mouse button was
pressed.

Instead, only consider left-click (and also middle-click and right-click
if --forward-all-clicks is enabled).
2021-06-20 12:34:19 +02:00
Romain Vimont
8b90e1d3f4 Remove extra ';' in #define 2021-06-20 12:34:19 +02:00
Romain Vimont
df017160ed Replace strcpy() by memcpy()
It was safe to call strcpy() since the input length was checked, but
then it is more straightforward to call memcpy() directly.
2021-06-20 12:34:19 +02:00
Romain Vimont
a1f2094787 Push to /sdcard/Download/ by default
Change the default push target from /sdcard/ to /sdcard/Download/.

Pushing to the root of /sdcard/ is not very convenient, many apps do not
expose its content directly.

It can still be changed by --push-target.

PR #2384 <https://github.com/Genymobile/scrcpy/pull/2384>
2021-06-16 22:56:11 +02:00
Romain Vimont
9b89b7ab72 Center the window on resize-to-fit
When removing the black borders (by double-clicking on them, or by
pressing MOD+w), the window is resized to fit the device screen, but its
top-left position was left unchanged.

Instead, move the window so that the new window area is at the center of
the old window area.

Refs #2387 <https://github.com/Genymobile/scrcpy/issues/2387>
2021-06-14 21:24:51 +02:00
Romain Vimont
7343b233e4 Render screen on window restored
It should not be necessary, since screen_render() is called just after
on SDL_WINDOWEVENT_EXPOSED, but in practice the window content might not
be correctly displayed on restored if a rotation occurred while
minimized.

Note that calling screen_render() twice in a row on
SDL_WINDOWEVENT_EXPOSED also "fixes" the issue.
2021-06-14 09:36:08 +02:00
Romain Vimont
cd2894570d Allocate AVPacket for v4l2_sink
From FFmpeg/doc/APIchanges:

    2021-03-17 - f7db77bd87 - lavc 58.133.100 - codec.h
      Deprecated av_init_packet(). Once removed, sizeof(AVPacket) will
      no longer be a part of the public ABI.

Refs #2302 <https://github.com/Genymobile/scrcpy/issues/2302>
2021-06-14 09:07:49 +02:00
Romain Vimont
4af317d40d Allocate AVPacket for recorder
From FFmpeg/doc/APIchanges:

    2021-03-17 - f7db77bd87 - lavc 58.133.100 - codec.h
      Deprecated av_init_packet(). Once removed, sizeof(AVPacket) will
      no longer be a part of the public ABI.

Refs #2302 <https://github.com/Genymobile/scrcpy/issues/2302>
2021-06-14 09:07:49 +02:00
Romain Vimont
318b6a572e Allocate AVPacket for local stream packet
From FFmpeg/doc/APIchanges:

    2021-03-17 - f7db77bd87 - lavc 58.133.100 - codec.h
      Deprecated av_init_packet(). Once removed, sizeof(AVPacket) will
      no longer be a part of the public ABI.

Refs #2302 <https://github.com/Genymobile/scrcpy/issues/2302>
2021-06-14 09:07:49 +02:00
Romain Vimont
e8b053ad2f Allocate AVPacket for stream->pending
From FFmpeg/doc/APIchanges:

    2021-03-17 - f7db77bd87 - lavc 58.133.100 - codec.h
      Deprecated av_init_packet(). Once removed, sizeof(AVPacket) will
      no longer be a part of the public ABI.

Remove the has_pending boolean, which can be replaced by:

    stream->pending != NULL

Refs #2302 <https://github.com/Genymobile/scrcpy/issues/2302>
2021-06-14 09:07:49 +02:00
Romain Vimont
af228706f1 Fix compatibility with old FFmpeg
V4L2 sink used a "url" field format AVFormatContext which has been
introduced in lavf 58.7.100.

Fixes #2382 <https://github.com/Genymobile/scrcpy/issues/2382>

Refs <ea3672b7d6>
Refs <fa8308d3d4>
2021-06-13 19:20:57 +02:00
Romain Vimont
f76fe2c0d4 Fix --lock-video-orientation syntax
The argument for option --lock-video-orientation has been made optional
by 5af9d0ee0f.

With getopt_long(), contrary to mandatory arguments, optional arguments
must be given with a '=':

    --lock-video-orientation 2   # wrong, parse error
    --lock-video-orientation=2   # correct
2021-06-11 18:40:12 +02:00
Romain Vimont
506f918fb7 Group components into struct scrcpy
This avoids to refer to many structs globally.
2021-05-28 21:29:14 +02:00
Romain Vimont
6fd7e89da1 Explicitly initialize decoder sink_count
The zero-initialization relied on the fact that the decoder instance is
static.
2021-05-28 21:23:18 +02:00
Romain Vimont
4c31911df2 Pass serial within struct server_params
This was the only option passed separately.
2021-05-28 21:21:54 +02:00
Romain Vimont
6adc97198b Provide device info directly on server connection
This avoids to retrieve them in a separate step.
2021-05-17 08:52:08 +02:00
Romain Vimont
6a2cd089a1 Initialize input manager dynamically
The input manager was partially initialized statically, but a call to
input_manager_init() was needed anyway, so initialize all the fields
from the "constructor".

This is consistent with the initialization of the other structs.
2021-05-17 08:48:51 +02:00
Romain Vimont
dcee7c0f7f Factorize screen_init() error management 2021-05-16 18:48:04 +02:00
Romain Vimont
e604e8a752 Move fps_counter to screen
The FPS counter specifically count frames from the screen video buffer,
so it is specific to the screen.
2021-05-16 18:47:16 +02:00
Romain Vimont
f19c455110 Fix leak on error
Destroy video buffer if screen window creation failed.
2021-05-16 18:46:47 +02:00
Romain Vimont
83116fc199 Notify end-of-stream via callback
Do not send a SDL event directly, to make stream independent of SDL.
2021-05-16 15:48:07 +02:00
Romain Vimont
1e64f0f931 Use ARRAY_LEN() macro 2021-05-09 11:06:02 +02:00
Romain Vimont
f062dfd30b Merge branch 'master' into dev 2021-05-09 11:00:30 +02:00
Romain Vimont
1b9dcce23c Fix double-free on error
On error, server->serial was freed twice: immediately and in
server_destroy().

Refs #2292 <https://github.com/Genymobile/scrcpy/issues/2292#issuecomment-831424820>
2021-05-03 20:43:45 +02:00
Romain Vimont
ae6ec7a194 Unref decoder AVFrame immediately
The frame can be unref immediately after it is pushed to the frame
sinks.

It was not really a memory leak because the frame was unref every time
by avcodec_receive_frame() (and freed on close), but a reference was
unnecessarily kept for too long.
2021-04-26 18:05:43 +02:00
Romain Vimont
84f17fdeab Fix v4l2 AVPacket memory leak on error
Unref v4l2 AVPacket even if writing failed.
2021-04-26 18:05:11 +02:00
Romain Vimont
1cde68a1fa Fix v4l2 AVFrame memory leak
Unref frame immediately once encoded.

Fixes #2279 <https://github.com/Genymobile/scrcpy/pull/2279>
2021-04-26 18:04:51 +02:00
Romain Vimont
45e7280148 Rename --v4l2_sink to --v4l2-sink
This was a rebase issue, the previous version in #2268 was correct.

Refs #2268 <https://github.com/Genymobile/scrcpy/pull/2268>
2021-04-26 17:59:35 +02:00
Marco Martinelli
d39161f753 Add support for v4l2loopback
It allows to send the video stream to /dev/videoN, so that it can be
captured (like a webcam) by any v4l2-capable tool.

PR #2232 <https://github.com/Genymobile/scrcpy/pull/2232>
PR #2233 <https://github.com/Genymobile/scrcpy/pull/2233>
PR #2268 <https://github.com/Genymobile/scrcpy/pull/2268>

Co-authored-by: Romain Vimont <rom@rom1v.com>
2021-04-25 14:59:10 +02:00
Romain Vimont
5af9d0ee0f Make --lock-video-orientation argument optional
If the option is set without argument, lock the initial device
orientation (as if the value "initial" was passed).
2021-04-25 14:55:54 +02:00
Romain Vimont
fd0dc6c0cd Add --lock-video-orientation=initial
Add a new mode to the --lock-video-orientation option, to lock the
initial orientation of the device.

This avoids to pass an explicit value (0, 1, 2 or 3) and think about
which is the right one.
2021-04-25 14:55:54 +02:00
Romain Vimont
151bc16644 Use strlist_contains() to find a muxer
The AVOutputFormat name is a string list: it contains names separated by
',' (possibly only one).
2021-04-25 14:55:19 +02:00
Romain Vimont
ffc00210e9 Add strlist_contains()
Add a function to know if a string list, using some separator, contains
a specific string.
2021-04-25 14:38:42 +02:00
Romain Vimont
243854a408 Fix recorder comment 2021-04-25 14:38:42 +02:00
Romain Vimont
8b90dc61b9 Handle EAGAIN on send_packet in decoder
EAGAIN was only handled on receive_frame.

In practice, it should not be necessary, since one packet always
contains one frame. But just in case.
2021-04-25 14:38:42 +02:00
Romain Vimont
2a5dfc1c17 Handle errors using gotos in recorder_open()
There are many initializations in recorder_open(). Handle RAII-like
deinitialization using gotos.
2021-04-25 14:38:42 +02:00
Romain Vimont
e3fccc5a5e Initialize recorder fields on open
Only initialize ops and parameters copy from recorder_init(). It was
inconsistent to initialize some fields from _init() and some others from
_open().
2021-04-25 14:38:42 +02:00
Romain Vimont
0541f1bff2 Hide the window immediately on close
The screen may not be destroyed immediately on close to avoid undefined
behavior, because it may still receive events from the decoder.

But the visual window must still be closed immediately.
2021-04-25 14:38:42 +02:00
Romain Vimont
0272e6dc77 Assert screen closed on destroy
The destruction order is important, but tricky, because the screen is
open/close by the decoder, but destroyed by scrcpy.c on the main thread.

Add assertions to guarantee that the screen is not destroyed before
being closed.
2021-04-25 14:38:42 +02:00
Romain Vimont
2a94a2b119 Remove video_buffer callbacks
Now that screen is both the owner and the listener of the video buffer,
execute the code directly without callbacks.
2021-04-25 14:38:42 +02:00
Romain Vimont
e91acdb0c4 Move video_buffer to screen
The video buffer is now an internal detail of the screen component.

Since the screen is plugged to the decoder via the frame sink trait, the
decoder does not access to the video buffer anymore.
2021-04-25 14:38:42 +02:00
Romain Vimont
6f5ad21f57 Make decoder push frames to sinks
Now that screen implements the packet sink trait, make decoder push
packets to the sinks without depending on the concrete sink types.
2021-04-25 14:38:42 +02:00
Romain Vimont
08b3086ffc Expose screen as frame sink
Make screen implement the frame sink trait.

This will allow the decoder to push frames without depending on the
concrete sink type.
2021-04-25 14:38:42 +02:00
Romain Vimont
deab7da761 Add frame sink trait
This trait will allow to abstract the concrete sink types from the frame
producer (decoder.c).
2021-04-25 14:38:42 +02:00
Romain Vimont
f7a1b67d66 Make stream push packets to sinks
Now that decoder and recorder implement the packet sink trait, make
stream push packets to the sinks without depending on the concrete sink
types.
2021-04-25 14:38:42 +02:00
Romain Vimont
cbed38799e Expose decoder as packet sink
Make decoder implement the packet sink trait.

This will allow the stream to push packets without depending on the
concrete sink type.
2021-04-25 14:38:42 +02:00
Romain Vimont
5beb7d6c02 Reorder decoder functions
This will make further commits more readable.
2021-04-25 14:38:42 +02:00
Romain Vimont
5980183a33 Expose recorder as packet sink
Make recorder implement the packet sink trait.

This will allow the stream to push packets without depending on the
concrete sink type.
2021-04-25 14:38:42 +02:00
Romain Vimont
fe8de893ca Privatize recorder threading
The fact that the recorder uses a separate thread is an internal detail,
so the functions _start(), _stop() and _join() should not be exposed.

Instead, start the thread on _open() and _stop()+_join() on close().

This paves the way to expose the recorder as a packet sink trait.
2021-04-25 14:38:42 +02:00
Romain Vimont
a974483c15 Reorder recorder functions
This will make further commits more readable.
2021-04-25 14:38:42 +02:00
Romain Vimont
1b072a24c4 Add packet sink trait
This trait will allow to abstract the concrete sink types from the
packet producer (stream.c).
2021-04-25 14:38:42 +02:00
Romain Vimont
08f1fd46c8 Add container_of() macro
This will allow to get the parent of an embedded struct.
2021-04-25 14:38:42 +02:00
Romain Vimont
2ddf760c09 Make video_buffer more generic
The video buffer took ownership of the producer frame (so that it could
swap frames quickly).

In order to support multiple sinks plugged to the decoder, the decoded
frame must not be consumed by the display video buffer.

Therefore, move the producer and consumer frames out of the video
buffer, and use FFmpeg AVFrame refcounting to share ownership while
avoiding copies.
2021-04-25 14:38:42 +02:00
Romain Vimont
5d9e96dc4e Remove compat with old FFmpeg codec params API
The new API has been introduced in 2016 in libavformat 57.xx, it's very
old.

This will avoid to maintain two code paths for codec parameters.
2021-04-25 14:38:42 +02:00
Romain Vimont
de9b79ec2d Remove compat with old FFmpeg decoding API
The new API has been introduced in 2016 in libavcodec 57.xx, it's very
old.

This will avoid to maintain two code paths for decoding.
2021-04-25 14:38:42 +02:00
Romain Vimont
55806e7d31 Remove option --render-expired-frames
This flag forced the decoder to wait for the previous frame to be
consumed by the display.

It was initially implemented as a compilation flag for testing, not
intended to be exposed at runtime. But to remove ifdefs and to allow
users to test this flag easily, it had finally been exposed by commit
ebccb9f6cc.

In practice, it turned out to be useless: it had no practical impact,
and it did not solve or mitigate any performance issues causing frame
skipping.

But that added some complexity to the codebase: it required an
additional condition variable, and made video buffer calls possibly
blocking, which in turn required code to interrupt it on exit.

To prepare support for multiple sinks plugged to the decoder (display
and v4l2 for example), the blocking call used for pacing the decoder
output becomes unacceptable, so just remove this useless "feature".
2021-04-25 14:38:42 +02:00
Romain Vimont
21b590b766 Write trailer from recorder thread
The recorder thread wrote the whole content except the trailer, which
was odd.
2021-04-25 14:38:42 +02:00
brunoais
b4ee9f27ce Add mouse shortcut to expand settings panel
Double-click on extra mouse button to open the settings panel (a
single-click opens the notification panel).

This is consistent with the keyboard shortcut MOD+n+n.

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

Signed-off-by: Romain Vimont <rom@rom1v.com>
2021-04-25 14:36:48 +02:00
brunoais
6fa63cf6f8 Add keyboard shortcut to expand settings panel
PR #2260 <https://github.com/Genymobile/scrcpy/pull/2260>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2021-04-25 14:36:48 +02:00
brunoais
50eecdab28 Add control message to expand settings panel
PR #2260 <https://github.com/Genymobile/scrcpy/pull/2260>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2021-04-25 14:36:48 +02:00
brunoais
9576283907 Count repeated identical key events
This will allow shortcuts such as MOD+n+n to open the settings panel.

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

Signed-off-by: Romain Vimont <rom@rom1v.com>
2021-04-25 14:36:48 +02:00
brunoais
66c581851f Rename control message type to COLLAPSE_PANELS
The collapsing action collapses any panels.

By the way, the Android method is named collapsePanels().

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

Signed-off-by: Romain Vimont <rom@rom1v.com>
2021-04-25 14:36:48 +02:00
Frank Leon Rose
aaf7875d92 Ensure get_server_path() retval is freeable
PR #2276 <https://github.com/Genymobile/scrcpy/pull/2276>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2021-04-22 22:12:23 +02:00
brunoais
b9c3f65fd8 Provide actions for the extra mouse buttons
Bind APP_SWITCH to button 4 and expand notification panel on button 5.

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

Signed-off-by: Romain Vimont <rom@rom1v.com>
2021-04-19 20:16:45 +02:00
Romain Vimont
d0739911a3 Forward DOWN and UP separately for right-click
The shortcut "back on screen on" is a bit special: the control is
requested by the client, but the actual event injection (POWER or BACK)
is determined on the device.

To properly inject DOWN and UP events for BACK, transmit the action as
a control parameter.

If the screen is off:
 - on DOWN, inject POWER (DOWN and UP) (wake up the device immediately)
 - on UP, do nothing
If the screen is on:
 - on DOWN, inject BACK DOWN
 - on UP, inject BACK UP

A corner case is when the screen turns off between the DOWN and UP
event. In that case, a BACK UP event will be injected, so it's harmless.

As a consequence of this change, the BACK button is now handled by
Android on mouse released. This is consistent with the keyboard shortcut
(Mod+b) behavior.

PR #2259 <https://github.com/Genymobile/scrcpy/pull/2259>
Refs #2258 <https://github.com/Genymobile/scrcpy/pull/2258>
2021-04-19 20:16:45 +02:00
Andrea Gelmini
498ad23e98 Fix typos
PR #2263 <https://github.com/Genymobile/scrcpy/pull/2263>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2021-04-18 14:36:31 +02:00
Romain Vimont
964b6d2243 Forward DOWN and UP separately for middle-click
As a consequence of this change, the HOME button is now handled by
Android on mouse released. This is consistent with the keyboard shortcut
(MOD+h) behavior.

PR #2259 <https://github.com/Genymobile/scrcpy/pull/2259>
Refs #2258 <https://github.com/Genymobile/scrcpy/pull/2258>
2021-04-17 18:04:24 +02:00
Romain Vimont
8cc057c8f1 Prevent forwarding only "mouse released" events
Some mouse clicks DOWN are captured for shortcuts, but the matching UP
events were still forwarded to the device.

Instead, capture both DOWN and UP for shortcuts, and do nothing on UP.

PR #2259 <https://github.com/Genymobile/scrcpy/pull/2259>
Refs #2258 <https://github.com/Genymobile/scrcpy/pull/2258>
2021-04-17 18:04:13 +02:00
Romain Vimont
edee69d637 Fix options alphabetical order
"verbosity" < "version"
2021-04-16 17:40:39 +02:00
Romain Vimont
8ef4c044fa Do not forward SDL_DROPFILE event
The event is handled by scrcpy.c, it is not necessary to send it to
screen or input_manager.
2021-04-13 22:37:08 +02:00
Romain Vimont
c23c38f99d Move resizing workaround to screen.c 2021-04-13 22:36:59 +02:00
Romain Vimont
65c4f487b3 Set initial fullscreen from screen.c 2021-04-13 22:15:05 +02:00
Romain Vimont
c6d7f5ee96 Make screen_show_window() static
It is only used from screen.c now.
2021-04-13 22:04:38 +02:00
Romain Vimont
28f6cbaea6 Destroy screen once stream is finished
The screen receives callbacks from the decoder, fed by the stream.

The decoder is run from the stream thread, so waiting for the end of
stream is sufficient to avoid possible use-after-destroy.
2021-04-11 14:42:09 +02:00
Romain Vimont
08fc6694e1 Do not destroy uninitialized screen
When --no-display was passed, screen_destroy() was called while
screen_init() was never called.

In practice, it did not crash because it just freed NULL pointers, but
it was still incorrect.
2021-04-11 13:07:44 +02:00
Romain Vimont
d0983db592 Make internal recorder function static 2021-04-10 18:48:52 +02:00
Romain Vimont
fb7870500a Remove unused field from input_manager 2021-04-10 18:48:52 +02:00
Romain Vimont
33006561c7 Remove useless forward declaration from stream.h 2021-04-10 18:48:52 +02:00
Romain Vimont
a09733d175 Remove useless includes from decoder.c 2021-04-10 18:48:44 +02:00
Romain Vimont
07a85b7c94 Fix typo in command-line help
Refs #2237 <https://github.com/Genymobile/scrcpy/issues/2237>
2021-04-07 15:12:33 +02:00
Romain Vimont
6231f683af Fix compilation error for old decoding API
Commits cb9c42bdcb and
441d3fb119 updated the code only for the
new decoding API.
2021-04-05 22:35:14 +02:00
Romain Vimont
9826c5c4a4 Remove HiDPI compilation flag
Always enable HiDPI support, there is no reason to expose a compilation
flag.
2021-04-04 15:00:13 +02:00
Yu-Chen Lin
1d615a0d51 Support power off on close
PR #824 <https://github.com/Genymobile/scrcpy/pull/824>

Signed-off-by: Yu-Chen Lin <npes87184@gmail.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2021-03-16 21:12:35 +01:00
Romain Vimont
eb7e1070cf Release frame data as soon as possible
During a frame swap, one of the two frames involved can be released.
2021-03-06 22:58:03 +01:00
Romain Vimont
386f017ba9 Factorize frame swap 2021-03-06 22:58:03 +01:00
Romain Vimont
cc48b24324 Simplify screen initialization
Use a single function to initialize the screen instance.
2021-03-06 22:58:03 +01:00
Romain Vimont
597c54f049 Group screen parameters into a struct
The function screen_init_rendering had too many parameters.
2021-03-06 22:58:03 +01:00
Romain Vimont
955da3b578 Remove screen static initializer
Most of the fields are initialized dynamically.
2021-03-06 22:58:03 +01:00
Romain Vimont
cb9c42bdcb Use a callback to notify frame skip
A skipped frame is detected when the producer offers a frame while the
current pending frame has not been consumed.

However, the producer (in practice the decoder) is not interested in the
fact that a frame has been skipped, only the consumer (the renderer) is.

Therefore, notify frame skip via a consumer callback. This allows to
manage the skipped and rendered frames count at the same place, and
remove fps_counter from decoder.
2021-03-06 22:58:03 +01:00
Romain Vimont
fb9f9848bd Use a callback to notify a new frame
Make the decoder independant of the SDL even mechanism, by making the
consumer register a callback on the video_buffer.
2021-03-06 22:58:03 +01:00
Romain Vimont
c50b958ee4 Initialize screen before starting the stream
As soon as the stream is started, the video buffer could notify a new
frame available.

In order to pass this event to the screen without race condition, the
screen must be initialized before the screen is started.
2021-03-06 22:58:03 +01:00
Romain Vimont
441d3fb119 Make video buffer more generic
Video buffer is a tool between a frame producer and a frame consumer.

For now, it is used between a decoder and a renderer, but in the future
another instance might be used to swscale decoded frames.
2021-03-06 22:58:03 +01:00
Romain Vimont
cb197ee3a2 Move fps counter out of video buffer
In order to make video buffer more generic, move out its specific
responsibility to count the fps between the decoder and the renderer.
2021-03-06 22:58:03 +01:00
yangfl
1863ca7ad1 Remove unnecessary escape characters in manpage
PR #2123 <https://github.com/Genymobile/scrcpy/pull/2123>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2021-02-27 17:53:40 +01:00
Romain Vimont
b16b65a715 Simplify default values
It makes sense to extract default values for bitrate and port range
(which are arbitrary and might be changed in the future).

However, the default values for "max size" and "lock video orientation"
are naturally unlimited/unlocked, and will never be changed. Extracting
these options just added complexity for no benefit, so hardcode them.
2021-02-25 22:19:05 +01:00
Romain Vimont
a3aa5ac95e Insert numerical values statically in usage string 2021-02-25 22:19:05 +01:00
Romain Vimont
0207e3df33 Remove unused no_window field 2021-02-25 22:19:05 +01:00
Romain Vimont
9cd1a7380d Enable NDEBUG via Meson built-in option 2021-02-25 22:19:05 +01:00
Romain Vimont
24b637b972 Handle im-related events from input_manager.c 2021-02-25 22:19:05 +01:00
Romain Vimont
76a3d9805b Inline window events handling
Now that all screen-related events are handled from screen.c, there is
no need for a separate method for window events.
2021-02-25 22:19:05 +01:00
Romain Vimont
50b4a730e3 Handle screen-related events from screen.c 2021-02-25 22:19:05 +01:00
Romain Vimont
ea2369f568 Reference video buffer from screen
This paves the way to handle EVENT_NEW_FRAME from screen.c, by allowing
to call screen_update_frame() without an explicit video_buffer instance.
2021-02-25 22:19:05 +01:00
Romain Vimont
0538e9645b Improve error handling in screen initialization
After the struct screen is initialized, the window, the renderer and the
texture are necessarily valid, so there is no need to check in
screen_destroy().
2021-02-25 22:18:51 +01:00
Romain Vimont
626094ad13 Handle window events only once visible
This will avoid corner cases where we need to resize while no frame has
been received yet.
2021-02-17 09:54:03 +01:00
Romain Vimont
a566635c43 Log mipmaps error only if mipmaps are enabled 2021-02-17 09:54:03 +01:00
Romain Vimont
862948b132 Make use_opengl local
The flag is used only locally, there is no need to store it in the
screen structure.
2021-02-17 09:54:03 +01:00
Romain Vimont
c0c4ba7009 Add intermediate frame in video buffer
There were only two frames simultaneously:
 - one used by the decoder;
 - one used by the renderer.

When the decoder finished decoding a frame, it swapped it with the
rendering frame.

Adding a third frame provides several benefits:
 - the decoder do not have to wait for the renderer to release the
   mutex;
 - it simplifies the video_buffer API;
 - it makes the rendering frame valid until the next call to
   video_buffer_take_rendering_frame(), which will be useful for
   swscaling on window resize.
2021-02-17 09:54:03 +01:00
Romain Vimont
c53bd4d8b6 Assert non-recursive usage of mutexes 2021-02-17 09:54:03 +01:00
Romain Vimont
54f5c42d7b Add mutex assertions 2021-02-17 09:54:03 +01:00
Romain Vimont
21d206f360 Expose mutex assertions
Add a function to assert that the mutex is held (or not).
2021-02-17 09:54:03 +01:00
Romain Vimont
d2689fc168 Expose thread id 2021-02-17 09:54:03 +01:00
Romain Vimont
f6320c7e31 Wrap SDL thread functions into scrcpy-specific API
The goal is to expose a consistent API for system tools, and paves the
way to make the "core" independant of SDL in the future.
2021-02-17 09:54:03 +01:00
Romain Vimont
30e619d37f Replace SDL_strdup() by strdup()
The functions SDL_malloc(), SDL_free() and SDL_strdup() were used only
because strdup() was not available everywhere.

Now that it is available, use the native version of these functions.
2021-02-17 09:54:03 +01:00
Romain Vimont
c0dde0fade Provide strdup() compat
Make strdup() available on all platforms.
2021-02-17 09:53:25 +01:00
Romain Vimont
ace438e52a Remove unused port_range field
The port_range is used from "struct server_params", the copy in
"struct server" was unused.
2021-02-14 14:47:49 +01:00
Romain Vimont
8e83f3e8af Remove unused custom event 2021-02-14 14:44:05 +01:00
Romain Vimont
97b001e7c0 Fix undefined left shift
Small unsigned integers promote to signed int. As a consequence, if v is
a uint8_t, then (v << 24) yields an int, so the left shift is undefined
if the MSB is 1.

Cast to uint32_t to yield an unsigned value.

Reported by USAN (meson x -Db_sanitize=undefined):

    runtime error: left shift of 255 by 24 places cannot be represented
    in type 'int'
2021-01-24 15:31:21 +01:00
Romain Vimont
d8e9ad20b0 Improve file handler error message
Terminating the file handler current process may be either a "push" or
"install" command.
2021-01-24 14:24:24 +01:00
Romain Vimont
b566700bfd Kill process with SIGKILL signal
An "adb push" command is not terminated by SIGTERM.
2021-01-24 14:24:24 +01:00
Romain Vimont
7afd149f4b Fix file_handler process race condition
The current process could be waited both by run_file_handler() and
file_handler_stop().

To avoid the race condition, wait the process without closing, then
close with mutex locked.
2021-01-24 14:24:24 +01:00
Romain Vimont
6a50231698 Expose a single process_wait()
There were two versions: process_wait() and process_wait_noclose().

Expose a single version with a flag (it was already implemented that way
internally).
2021-01-24 14:24:18 +01:00
Romain Vimont
b8edcf52b0 Simplify process_wait()
The function process_wait() returned a bool (true if the process
terminated successfully) and provided the exit code via an output
parameter exit_code.

But the returned value was always equivalent to exit_code == 0, so just
return the exit code instead.
2021-01-22 18:29:21 +01:00
Romain Vimont
94eff0a4bb Fix size_t incorrectly assigned to int
The function control_msg_serialize() returns a size_t.
2021-01-17 19:44:23 +01:00
Romain Vimont
8dbb1676b7 Factorize meson compiler variable initialization 2021-01-17 19:44:23 +01:00
Romain Vimont
ab912c23e7 Define feature test macros in common.h
This enables necessary functions once for all.

As a consequence, define common.h before any other header.
2021-01-17 14:08:48 +01:00
Romain Vimont
59feb2a15c Group common includes into common.h
Include config.h and compat.h in common.h, and include common.h from all
source files.
2021-01-08 19:22:10 +01:00
Romain Vimont
6385b8c162 Move common structs to coords.h
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.
2021-01-08 19:22:10 +01:00
Romain Vimont
037be4af21 Fix compat missing include
The header libavformat/version.h was included, but not
libavcodec/version.h.

As a consequence, the LIBAVCODEC_VERSION_INT definition depended on the
caller includes.
2021-01-08 19:21:54 +01:00
Romain Vimont
1e215199dc Remove unused struct port_range
It had been replaced by struct sc_port_range in scrcpy.h.
2021-01-08 19:13:53 +01:00
Romain Vimont
d580ee30f1 Separate process wait and close
On Linux, waitpid() both waits for the process to terminate and reaps it
(closes its handle). On Windows, these actions are separated into
WaitForSingleObject() and CloseHandle().

Expose these actions separately, so that it is possible to send a signal
to a process while waiting for its termination without race condition.

This allows to wait for server termination normally, but kill the
process without race condition if it is not terminated after some delay.
2021-01-08 16:44:21 +01:00
Romain Vimont
821c175730 Rename process_simple_wait to process_wait
Adding "simple" in the function name brings no benefit.
2021-01-08 16:44:21 +01:00
Romain Vimont
cc6f5020d8 Move conditional src files in meson.build
Declare all the source files (including the platform-specific ones) at
the beginning.
2021-01-08 16:44:21 +01:00
Romain Vimont
4bd9da4c93 Split command into process and adb
The process API provides the system-specific implementation, the adb API
uses it to expose adb commands.
2021-01-08 16:44:21 +01:00
Romain Vimont
aa8b571389 Increase display id range
Some devices use big display id values.

Refs #2009 <https://github.com/Genymobile/scrcpy/issues/2009>
2021-01-04 08:16:32 +01:00
Romain Vimont
ed130e05d5 Fix possibly uninitialized value
Due to gotos, "ret" may be returned uninitialized.
2021-01-03 22:41:51 +01:00