Commit Graph

171 Commits

Author SHA1 Message Date
Romain Vimont
00e4800b0c Add session metadata for video stream
Introduce a new packet type, a "session" packet, containing metadata
about the encoding session. It is used only for the video stream,
and currently includes the video resolution.

For illustration, here is a sequence of packets on the video stream:

                                        device rotation
                                        v
    CODEC | SESSION | MEDIA | MEDIA | … | SESSION | MEDIA | MEDIA | …
           1920x1080 <-----------------> 1080x1920 <------------------
                      encoding session 1            encoding session 2

This metadata is not strictly necessary, since the video resolution can
be determined after decoding. However, it allows detection of cases
where the encoder does not respect the requested size (and logs a
warning), even without decoding (e.g., when there is no video playback).

Additional metadata could be added later if necessary, for example the
actual device rotation.

Refs #5918 <https://github.com/Genymobile/scrcpy/pull/5918>
Refs #5894 <https://github.com/Genymobile/scrcpy/pull/5894>

Co-authored-by: gz0119 <liyong2@4399.com>
2025-11-28 22:44:12 +01:00
Romain Vimont
252c234cb1 Migrate from SDL2 to SDL3
Refs <https://wiki.libsdl.org/SDL3/README-migration>
2025-11-28 22:44:12 +01:00
Romain Vimont
5d3a0e14c3 Improve color space conversion
Use both the color space and color range from FFmpeg to determine the
appropriate SDL YUV conversion mode.
2025-11-28 22:44:12 +01:00
Romain Vimont
1917f1c427 Set color range during texture creation
This prepares for the migration to SDL3, where the color range can only
be specified at the time of texture creation.
2025-11-28 22:44:12 +01:00
Romain Vimont
44761099eb Create texture on first frame
The texture was created as soon as the initial video size was known,
even before the first frame arrived.

However, texture creation will require other data, such as the color
range, which is only available once the first frame is received.

Therefore, delay texture creation until the first frame.
2025-11-28 22:44:12 +01:00
Romain Vimont
993bc729d4 Remove prepare_for_frame()
Inline the function body in its only caller.

This will simplify further refactors.
2025-11-28 22:44:12 +01:00
Romain Vimont
eb576c44f8 Replace __WINDOWS__ by _WIN32
Replace the SDL2-specific preprocessor macro __WINDOWS__ by the
"standard" _WIN32 macro.
2025-07-17 18:23:25 +02:00
Romain Vimont
04542a9f58 Fix window leak on icon error 2025-07-17 13:19:15 +02:00
Romain Vimont
ff9fb5994d Use shortcut mods as mouse capture keys
Instead of using separate hardcoded keys for mouse capture/uncapture,
use the shortcut mods.

By changing the shortcut mods (for example --shortcut-mod=rctrl), it
allows to forward Alt and Super to the device.

Fixes #5318 <https://github.com/Genymobile/scrcpy/issues/5318>
PR #5322 <https://github.com/Genymobile/scrcpy/pull/5322>
2024-10-06 18:01:02 +02:00
Romain Vimont
281fcc7052 Extract mouse capture
Factorize mouse capture for relative mouse mode to reduce code
duplication between normal and OTG modes.

PR #5322 <https://github.com/Genymobile/scrcpy/pull/5322>
2024-10-06 18:00:56 +02:00
Romain Vimont
d92b7a6024 Rename switch_fullscreen() to toggle_fullscreen()
Toggle means to switch between two states.
2024-09-25 19:59:49 +02:00
Romain Vimont
4565f36ee6 Handle SDL gamepad events
Introduce a gamepad processor trait, similar to the keyboard processor
and mouse processor traits.

Handle gamepad events received from SDL, convert them to scrcpy-specific
gamepad events, and forward them to the gamepad processor.

Further commits will provide AOA and UHID implementations of the gamepad
processor trait.

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

Co-authored-by: Luiz Henrique Laurini <luizhenriquelaurini@gmail.com>
2024-09-15 11:21:56 +02:00
Romain Vimont
e9b32d8a52 Extract sc_push_event()
Expose a convenience function to push an event without args to the main
thread.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-14 21:24:15 +02:00
Romain Vimont
dea1fe3386 Validate crop and video size
A video width or height of 0 triggered an assert.

Fail explicitly instead: the server may actually send this size in
practice (for example on cropping with small dimensions, even if the
requested crop size is not 0).
2024-09-13 19:48:55 +02:00
Romain Vimont
035d60cf5d Add option to configure mouse bindings
Add a new option --mouse-bind=xxxx.

The argument must be exactly 4 characters, one for each secondary click:

    --mouse-bind=xxxx
                 ^^^^
                 ||||
                 ||| `- 5th click
                 || `-- 4th click
                 | `--- middle click
                  `---- right click

Each character must be one of the following:
 - `+`: forward the click to the device
 - `-`: ignore the click
 - `b`: trigger shortcut BACK (or turn screen on if off)
 - `h`: trigger shortcut HOME
 - `s`: trigger shortcut APP_SWITCH
 - `n`: trigger shortcut "expand notification panel"

This deprecates --forward-all-clicks (use --mouse-bind=++++ instead).

Refs <https://github.com/Genymobile/scrcpy/pull/2258#issuecomment-2182394460>
PR #5022 <https://github.com/Genymobile/scrcpy/pull/5022>
2024-06-24 23:17:23 +02:00
Romain Vimont
45fe6b602b Add scrcpy window without video playback
Add the possibility to solely control the device without screen
mirroring:

    scrcpy --no-video --no-audio

This is different from OTG mode, which does not require USB debugging at
all. Here, the standard mode is used but with the possibility to disable
video playback.

By default, always open a window (even without video playback), and add
an option --no-window.

Fixes #4727 <https://github.com/Genymobile/scrcpy/issues/4727>
Fixes #4793 <https://github.com/Genymobile/scrcpy/issues/4793>
PR #4868 <https://github.com/Genymobile/scrcpy/pull/4868>
2024-05-11 17:06:16 +02:00
Romain Vimont
1c3801a0b1 Add a shortcut to pause/unpause display
Pause/unpause display on MOD+z and MOD+Shift+z.

It only impacts rendering, the device is still captured, the video
stream continues to be transmitted to the device and recorded (if
recording is enabled).

Fixes #1632 <https://github.com/Genymobile/scrcpy/issues/1632>
PR #4748 <https://github.com/Genymobile/scrcpy/pull/4748>
2024-03-30 14:20:51 +01:00
Romain Vimont
bb88b60227 Add --display-orientation
Deprecate the option --rotation and introduce a new option
--display-orientation with the 8 possible orientations (0, 90, 180, 270,
flip0, flip90, flip180 and flip270).

New shortcuts MOD+Shift+(arrow) dynamically change the display
(horizontal or vertical) flip.

Fixes #1380 <https://github.com/Genymobile/scrcpy/issues/1380>
Fixes #3819 <https://github.com/Genymobile/scrcpy/issues/3819>
PR #4441 <https://github.com/Genymobile/scrcpy/pull/4441>
2023-11-23 23:27:28 +01:00
Romain Vimont
85b55b3c4e Fix possible division by zero
On sway (a window manager), SDL_WINDOWEVENT_EXPOSED and
SDL_WINDOWEVENT_SIZE_CHANGED might not be called before a mouse event is
triggered. As a consequence, the "content rectangle" might not be
initialized when the mouse event is processed, causing a division by
zero.

To avoid the problem, initialize the content rect immediately when the
window is shown.

Fixes #4115 <https://github.com/Genymobile/scrcpy/issues/4115>
2023-06-29 19:18:32 +02:00
Romain Vimont
e926bf1fe8 Delay window resize when minimized
On some window managers (e.g. on Windows), performing a resize while the
window is minimized does nothing (the restored window keeps its old
size).

Therefore, like for maximized and fullscreen states, wait for the window
to be restored to apply a resize.

Refs #3947 <https://github.com/Genymobile/scrcpy/issues/3947>
2023-05-22 18:22:45 +02:00
Romain Vimont
6298ef095f Accept texture failures
When the scrcpy window is minimized on Windows with D3D9, texture
creation and update fail.

In that case, do not terminate scrcpy. Instead, store the pending size
or frame to update, to attempt again during the next update or
rendering.

Fixes #3947 <https://github.com/Genymobile/scrcpy/issues/3947>
2023-05-22 18:21:10 +02:00
Romain Vimont
051b74c883 Extract sc_display from sc_screen
Move the display code to a separate component.
2023-04-06 19:48:26 +02:00
Romain Vimont
2e532afd2b Pass const pointers to events
SDL_Events are only read.
2023-04-06 19:48:01 +02:00
Ruoyu Zhong
6b769675fa Fix an "expected expression" error
In C, a label can only be followed by a statement, not a declaration.
An error in `app/src/screen.c` violated this, and led to a build error
with an error message similar to the one below:

    ../app/src/screen.c:821:13: error: expected expression
                bool ok = sc_screen_init_size(screen);
                ^
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/13.0.0/include/stdbool.h:15:14: note: expanded from macro 'bool'
    #define bool _Bool
                 ^
    ../app/src/screen.c:822:18: error: use of undeclared identifier 'ok'
                if (!ok) {
                     ^
    2 errors generated.

This could be fixed by introducing a new block (or compound statement;
as is already being done in the next `case`). That is a statement.

Fixes #3785 <https://github.com/Genymobile/scrcpy/issues/3785>
PR #3787 <https://github.com/Genymobile/scrcpy/pull/3787>

Signed-off-by: Ruoyu Zhong <zhongruoyu@outlook.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2023-03-12 08:26:17 +01:00
Romain Vimont
238ab872ba Pass video size as codec metadata
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.
2023-03-11 15:57:25 +01:00
Romain Vimont
3a72f3fb4d Report errors on screen event error
Make scrcpy fail if an important screen event (like frame update) fails.
2023-03-11 15:57:25 +01:00
Romain Vimont
1230149fdd Use delay buffer as a frame source/sink
The components needing delayed frames (sc_screen and sc_v4l2_sink)
managed a sc_video_buffer instance, which itself embedded a
sc_frame_buffer instance (to keep only the most recent frame).

In theory, these components should not be aware of delaying: they should
just receive AVFrames later, and only handle a sc_frame_buffer.

Therefore, refactor sc_delay_buffer as a frame source (it consumes)
frames) and a frame sink (it produces frames, after some delay), and
plug an instance in the pipeline only when a delay is requested.

This also removes the need for a specific sc_video_buffer.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
4540f1d69e Report video buffer downstream errors
Make the video buffer stop if its consumer could not receive a frame.
2023-03-10 22:22:15 +01:00
Romain Vimont
619730edaf Pass AVCodecContext to frame sinks
Frame consumers may need details about the frame format.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
4f9e9c6619 Prefix UI events constants by SC_ 2023-02-10 18:55:43 +01:00
Romain Vimont
d8c2fe6ef2 Revert "Remove continuous resizing workaround for Windows"
This reverts commit 18082f6069.

I can't reproduce, but it seems the workaround improves the behavior on
some Windows versions.

Fixes #3640 <https://github.com/Genymobile/scrcpy/issues/3640>
Refs #3458 <https://github.com/Genymobile/scrcpy/issues/3458>
2022-12-26 12:42:59 +01:00
Romain Vimont
18082f6069 Remove continuous resizing workaround for Windows
It turns out that the workaround only worked for MacOS.

Refs #3458 <https://github.com/Genymobile/scrcpy/issues/3458>
Refs SDL/#1059 <https://github.com/libsdl-org/SDL/issues/1059>
2022-12-21 22:06:43 +01:00
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