Commit graph

139 commits

Author SHA1 Message Date
Romain Vimont
3ee3f8dc02 Work around mouse capture SDL bug on macOS
On macOS, SDL relative mouse mode does not work correctly when the
cursor is outside the window.

As a workaround, move the cursor inside the window before setting the
relative mouse mode.

Refs SDL/#5340 <https://github.com/libsdl-org/SDL/issues/5340>
PR #3031 <https://github.com/Genymobile/scrcpy/pull/3031>
2022-02-20 17:28:02 +01:00
Romain Vimont
9db42341e4 Pass screen instance to mouse capture functions
Using the screen instance or not in these functions is an implementation
detail. Further changes will require the screen instance.

Refs 7848a387c8
PR #3031 <https://github.com/Genymobile/scrcpy/pull/3031>
2022-02-20 17:27:53 +01:00
Romain Vimont
4b018be789 Add --print-fps to enable FPS counter on start
The FPS counter could be enabled/disabled via MOD+i.

Add a command line option to enable it on start. This is consistent with
other features like --turn-screen-off or --fullscreen.

Fixes #468 <https://github.com/Genymobile/scrcpy/issues/468>
PR #3030 <https://github.com/Genymobile/scrcpy/pull/3030>
2022-02-18 18:16:50 +01:00
Romain Vimont
03705b828b Use sc_prefix for fps counter 2022-02-17 19:55:24 +01:00
Romain Vimont
7848a387c8 Do not duplicate relative mouse mode state
The relative mouse mode is tracked by SDL, and accessible via
SDL_GetRelativeMouseMode().

This is more robust in case SDL changes the relative mouse mode on its
own.
2022-02-10 08:50:18 +01:00
Romain Vimont
61b6324ee9 Remove LOGC()
It is not clear when to use LOGC() rather than LOGE(). Always use
LOGE().

Moreover, enum sc_log_level has no "critical" log level.
2022-02-09 09:52:15 +01:00
Romain Vimont
063d103dd6 Capture mouse on start for --hid-mouse
If relative mode is enabled, capture the mouse immediately.
2022-01-23 21:31:53 +01:00
Romain Vimont
4bf9c057fe Extract relative mode check to an inline function
This will allow to reuse the condition in another function.
2022-01-23 21:31:11 +01:00
Romain Vimont
17c97820b2 Never forward capture keys
In relative mode, Alt and Super are "capture keys". Never forward them
to the input manager, to avoid inconsistencies between UP and DOWN
events.
2022-01-23 21:16:40 +01:00
Romain Vimont
ac038f276e Add missing break statement
This was harmless because this is the last "case" of the switch, but for
consistency, add the missing break.
2022-01-23 15:01:11 +01:00
Romain Vimont
1f65b1bf87 Remove inline hint
There is no reason to request inlining here.
2022-01-23 15:01:11 +01:00
Romain Vimont
855819bbd8 Remove redundant control boolean
The controller is NULL if and only if control is disabled, so an
additional control boolean is redundant.
2022-01-23 12:16:24 +01:00
Romain Vimont
0ec3361bc9 Fix crash on --no-control
Relative mouse mode assumed that a mouse processor was always available,
but this is not the case if --no-control is passed.
2022-01-23 12:16:07 +01:00
Romain Vimont
1ffe312369 Handle file drop from input_manager
A file is pushed (or an apk is installed) to the device on file drop.
This behavior is specific to the screen and its input_manager.
2022-01-21 21:52:41 +01:00
Romain Vimont
ebef027c4f Do not return status for event handling
It is never read. Simplify.
2022-01-21 21:52:41 +01:00
Romain Vimont
75c5dc6859 Position and size the window on first frame
The optimal initial size was computed from the expected dimensions, sent
immediately by the server before encoding any video frame.

However, the actual frame size may be different, for example when the
device encoder does not support the requested size.

To always handle this case properly, position and size the window only
once the first frame size is known.

PR #2947 <https://github.com/Genymobile/scrcpy/pull/2947>
2022-01-21 18:43:46 +01:00
Romain Vimont
fa30f9806a Move "show window" call on first frame
Show the window only after the actual frame size is known (and if no
error has occurred).

This will allow to properly position and size the window when the size
of the first frame is different from the size initially announced by the
server.

PR #2947 <https://github.com/Genymobile/scrcpy/pull/2947>
2022-01-21 18:42:39 +01:00
Romain Vimont
5f7ddff8ae Use sc_ prefix for input_manager 2022-01-14 22:17:30 +01:00
Romain Vimont
2a0c2e5e99 Use sc_ prefix for screen 2022-01-14 22:17:30 +01:00
Romain Vimont
17d01b5bf7 Add UI/UX support for relative mouse mode
In relative mouse mode, the mouse pointer must be "captured" from the
computer.

Toggle (disable/enable) relative mouse mode using any of the hardcoded
capture keys:
 - left-Alt
 - left-Super
 - right-Super

These capture keys do not conflict with shortcuts, since a shortcut is
always a combination of the MOD key and some other key, while the
capture key triggers an action only if it is pressed and released alone.

The relative mouse mode is also automatically enabled on any click in
the window, and automatically disabled on focus lost (it is possible to
lose focus even without the mouse).
2022-01-04 17:41:40 +01:00
Romain Vimont
6102a0b5bb Move input_manager into screen
The input_manager is strongly tied to the screen, it could not work
independently of the specific screen implementation.

To implement a user-friendly HID mouse behavior, some SDL events
will need to be handled both by the screen and by the input manager. For
example, a click must typically be handled by the input_manager so that
it is forwarded to the device, but in HID mouse mode, the first click
should be handled by the screen to capture the mouse (enable relative
mouse mode).

Make the input_manager a descendant of the screen, so that the screen
decides what to do on SDL events.

Concretely, replace this structure hierarchy:

     +- struct scrcpy
        +- struct input_manager
        +- struct screen

by this one:

     +- struct scrcpy
        +- struct screen
           +- struct input_manager
2022-01-04 17:41:35 +01:00
Romain Vimont
6261bb0b5a Ignore display bounds on resize-to-fit
The "resize to fit" feature (MOD+w or double-click on black borders)
computed the "optimal size" using the same function computing the
initial window size on start.

However, on "resize to fit", only the black borders must be removed (the
content size must be preserved), so the display bounds must not be
considered.
2021-12-20 19:24:28 +01:00
Romain Vimont
2f091beeaa Simplify sc_size assignment
Assign the whole struct instead of each field separately.
2021-12-20 19:24:28 +01:00
Romain Vimont
dca2c5f94f Require SDL >= 2.0.5
Icon loading uses SDL_CreateRGBSurfaceWithFormatFrom(), available since
SDL 2.0.5 (in 2016).

Refs #2862 <https://github.com/Genymobile/scrcpy/issues/2862>
2021-12-06 23:49:55 +01:00
Romain Vimont
3653fb6b15 Add OutOfMemory log helper
Add a special LOG_OOM() function to log all OutOfMemory errors (i.e.
allocations returning NULL).
2021-11-24 22:06:49 +01:00
Romain Vimont
be55e250ca Make screen_render() static
It is only used from screen.c.
2021-11-12 22:44:22 +01:00
Romain Vimont
dae091e3ab Handle SDL_PushEvent() errors
Pushing an event to the main thread may fail. If this happens, log an
error, and try to recover when possible.
2021-10-30 20:25:20 +02:00
Romain Vimont
4c4381de4c Use sc_ prefix for size, position and point 2021-10-30 15:20:39 +02:00
Romain Vimont
e4d5c1ce36 Move scrcpy option structs to options.h
This will allow to define symbols in options.c without all the
dependencies of scrcpy.c.
2021-10-27 18:43:47 +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
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
336248df08 Rename video_buffer to sc_video_buffer
Add a scrcpy-specific prefix.
2021-07-14 14:22:32 +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
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
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
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
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
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
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
Romain Vimont
cc48b24324 Simplify screen initialization
Use a single function to initialize the screen instance.
2021-03-06 22:58:03 +01:00