Mouse and keyboard events with unknown button/keycode/scancode cannot be
handled properly. Discard them without forwarding them to the
keyboard or mouse processors.
This can happen for example if a more recent version of SDL introduces
new enum values.
PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
Now that the AOA open/close are asynchronous, an open error did not make
scrcpy exit anymore.
Add a mechanism to exit if the AOA device could not be opened
asynchronously.
PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
Pushing a close event from the keyboard_aoa or mouse_aoa implementation
was racy, because the AOA thread might be stopped before these events
were processed.
Instead, keep the list of open AOA devices to close them automatically
from the AOA thread before exiting.
PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
This allows to handle HID open/close reports at the same place as HID
input reports (in the HID layer).
This will be especially useful to manage HID gamepads, to avoid
implementing one part in the HID layer and another part in the gamepad
processor implementation.
PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
For AOA keyboard and mouse, only input reports were asynchronous.
Register/unregister were called from the main thread.
This had the benefit to fail immediately if the AOA registration failed,
but we want to open/close AOA devices dynamically in order to add
gamepad support.
PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
The HID ids (accessory ids or UHID ids) were defined by the keyboard and
mouse implementations.
Instead, define them in the common HID part, and make that id part of
the sc_hid_event.
This prepares the introduction of gamepad support, which will handle
several gamepads (and ids) in the common HID gamepad code.
PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
Control messages are queued from the main thread and sent to the device
from a separate thread.
When the queue is full, messages are just dropped. This avoids to
accumulate too much delay between the client and the device in case of
network issue.
However, some messages should not be dropped: for example, dropping a
UHID_CREATE message would make all further UHID_INPUT messages invalid.
Therefore, mark these messages as non-droppable.
A non-droppable event is queued anyway (resizing the queue if
necessary, unless the allocation fails).
PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
This allows to schedule a runnable to be executed on the main thread,
until the event loop is explicitly terminated.
It is guaranteed that all accepted runnables will be executed (this
avoids possible memory leaks if a runnable owns resources).
PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
It is better to disable Nagle's algorithm to avoid unnecessary latency
for control messages. (I'm not sure this has any impact for a local TCP
socket though.)
Many parsing and formatting C functions like strtof() and asprintf() are
locale-dependent. Forcing a C locale just for the conversions in a way
that works on all platforms is a mess.
In practice, this is not a problem, scrcpy always uses the C locale,
because it never calls:
setlocale(LC_ALL, "");
But the max-fps option should not depend on the locale configuration
anyway.
Since the value is parsed by the client in Java anyway, just forward the
string value as is.
Android accepts a float value, there is no reason to limit the option
to be an integer.
In particular, it allows to capture at a rate lower than 1 fps. For
example, to capture 1 frame every 5 seconds:
scrcpy --video-source=camera --max-fps=0.2
It was already possible to pass a float manually:
scrcpy --video-source=camera \
--video-codec-options=max-fps-to-encoder:float=0.2
But accepting a float directly for --max-fps is more convenient.
Refs <https://developer.android.com/reference/android/media/MediaFormat#KEY_MAX_FPS_TO_ENCODER>
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).
The delay buffer clock estimates the clock offset between the PTS and
the frame decoded date using an "Exponentially Weighted Moving Average"
(EWMA).
But for the first frames, the clock have less than SC_CLOCK_RANGE
points to average. Since the timing for the first frames are typically
the worst ones, give more weight to the last point for the estimation.
Once SC_CLOCK_RANGE points are available (i.e. when SC_CLOCK_RANGE ==
clock->range), the new estimation is equivalent to the previous version.
The delay buffer `stopped` field was not initialized.
Since it practice the unique instance of sc_delay_buffer is initialized
in static memory, the flag was initialized to false as a side effect.
But with commit fd0f432e87, in debug mode
only, the delay buffer was broken.
"Could not" implies that the system tried to disable the option but
encountered an issue or failure.
"Cannot" indicates a rule or restriction, meaning it's not possible to
perform the action at all.
By default, the audio source is initialized to SC_AUDIO_SOURCE_AUTO, and
is "resolved" only if audio is enabled.
But the server arguments were built assuming that the audio source was
never SC_AUDIO_SOURCE_AUTO (even with audio disabled), causing a crash.
Regression introduced by a10f8cd798.
Automatically switch implicit audio source to "playback" if --audio-dup
is passed.
This allows to run:
scrcpy --audio-dup
without specifying explicitly:
scrcpy --audio-source=playback --audio-dup
PR #5102 <https://github.com/Genymobile/scrcpy/pull/5102>
Add a new method to capture audio playback.
It requires Android 13 (where the Shell app has MODIFY_AUDIO_ROUTING
permission).
The main benefit is that it supports keeping audio playing on the device
(implemented in a further commit).
Fixes#4380 <https://github.com/Genymobile/scrcpy/issues/4380>
PR #5102 <https://github.com/Genymobile/scrcpy/pull/5102>
Co-authored-by: Simon Chan <1330321+yume-chan@users.noreply.github.com>
Passing an unknown enum value to convert them to string would return
NULL without any error, possibly causing undefined behavior later.
Add assertions to catch such programming errors early.
Add secondary bindings (Shift+click) for mouse buttons.
In addition to:
--mouse-bind=xxxx
It is now possible to pass a sequence of secondary bindings:
--mouse-bind=xxxx:xxxx
<--> <-->
primary secondary
bindings bindings
If the second sequence is omitted, then it is the same as the first one.
By default, for SDK mouse, primary bindings trigger shortcuts and
secondary bindings forward all clicks.
For AOA and UHID, the default bindings are reversed: all clicks are
forwarded by default, whereas pressing Shift+click trigger shortcuts.
--mouse-bind=bhsn:++++ # default for SDK
--mouse-bind=++++:bhsn # default for AOA and UHID
Refs 035d60cf5d
Refs f5e6b8092aFixes#5055 <https://github.com/Genymobile/scrcpy/issues/5055>
PR #5076 <https://github.com/Genymobile/scrcpy/pull/5076>
The buttons state was tracked by SDL_GetMouseState(), and scrcpy applied
a mask to ignore buttons used for shortcuts.
Instead, track the buttons actually pressed (ignoring shortcuts)
manually, to prepare the introduction of more dynamic mouse shortcuts.
PR #5076 <https://github.com/Genymobile/scrcpy/pull/5076>
For pinch-to-zoom, rotation and tilt simulation, always use a finger
source (instead of a mouse) for both pointers (the real one and the
simulated one).
A "virtual" mouse does not work on all devices (e.g. on Pixel 8).
PR #5076 <https://github.com/Genymobile/scrcpy/pull/5076>
A device disconnection (when the adb connection is closed) makes the
read() on the "receiver" socket fail.
Since commit 063a8339ed, this is reported
as an error. As a consequence, scrcpy fails with:
ERROR: Controller error
instead of:
WARN: Device disconnected
To fix the issue, report a device disconnection in that case.
PR #5044 <https://github.com/Genymobile/scrcpy/pull/5044>
This also avoids a warning with some compilers which do not understand
that the condition to initialize the variable is the same as the
condition to use it:
../app/src/scrcpy.c: In function ‘scrcpy’:
../app/src/scrcpy.c:750:13: warning: ‘src’ may be used uninitialized in this function [-Wmaybe-uninitialized]
750 | sc_frame_source_add_sink(src, &s->screen.frame_sink);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Refs 45fe6b602b
Refs <https://github.com/Genymobile/scrcpy/issues/5045#issuecomment-2201589757>
The documentation of avcodec_close() says:
> Do not use this function. Use avcodec_free_context() to destroy a
> codec context (either open or closed).
It was deprecated in FFmpeg 7 by commit
1cc24d749569a42510399a29b034f7a77bdec34e:
<1cc24d7495>
> Its use has been discouraged since 2016, but now is no longer used in
> avformat, so there is no reason to keep it public.
By default, only the left click is forwarded to the device, and
secondary clicks trigger shortcuts (the behavior can be configured by
--mouse-bind=xxxx).
But when the mouse mode is relative (AOA and UHID modes), forward all
clicks by default. This makes more sense since the cursor is handled on
the device side, the user expects all mouse buttons to be forwarded.
Refs <https://github.com/Genymobile/scrcpy/issues/4727#issuecomment-2069869750>
PR #5022 <https://github.com/Genymobile/scrcpy/pull/5022>
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>
To resize the window to fit the device screen, it is possible to
double-click in the "black bars".
This feature was mistakenly disabled when --forward-all-clicks was set.
Instead, disable it only if mouse relative mode is enabled (AOA or
UHID), because in that case the mouse cursor is on the device.
Restrict shortcut modifiers to be composed of only one item each.
Before, it was possible to select a list of multiple combinations of
modifier keys, like --shortcut-mod='lctrl+lalt,rctrl+rsuper', meaning
that shortcuts would be triggered either by LCtrl+LAlt+key or
RCtrl+RSuper+key.
This was overly generic, probably not used very much, and it prevents to
solve inconsistencies between UP and DOWN events of modifier keys sent
to the device.
Refs #4732 <https://github.com/Genymobile/scrcpy/issues/4732>
PR #4741 <https://github.com/Genymobile/scrcpy/pull/4741>
Do not call sc_screen_hide_window() if screen is not initialized.
To reproduce:
scrcpy --no-video --record=file.mp4
This only segfaults in debug mode since commit
fd0f432e87.
The project has 3 build dependencies:
- SDL
- FFmpeg
- libusb
For Windows, the release script downloaded pre-built build dependencies
(either from upstream, or from the scrcpy-deps repository).
Instead, download the source releases and build locally. This offers
more flexibility.
The official adb release is still downloaded and included as is in the
release archive (it is not a build dependency).
Also upgrade FFmpeg to 6.1.1 and libusb to 1.0.27.
PR #4713 <https://github.com/Genymobile/scrcpy/pull/4713>
Initially, if AOA initialization failed, default injection method was
used, in order to use the same command/shortcut when the device is
connected via USB or via TCP/IP, without changing the arguments.
Now that there are 3 keyboard modes, it seems unexpected to switch to
another specific mode if AOA fails (and it is inconsistent). If the user
explicitly requests AOA, then use AOA or fail.
Refs #2632 comment <https://github.com/Genymobile/scrcpy/pull/2632#issuecomment-945190859>
PR #4473 <https://github.com/Genymobile/scrcpy/pull/4473>
The options were deprecated, but for convenience, reassign them to
aliases for --keyboard=uhid and --mouse=uhid respectively.
Their long version (--hid-keyboard and --hid-mouse) remain deprecated.
PR #4473 <https://github.com/Genymobile/scrcpy/pull/4473>
The keyboard settings can be opened by:
adb shell am start -a android.settings.HARD_KEYBOARD_SETTINGS
Add a shortcut (MOD+k) for convenience if the current keyboard is HID.
PR #4473 <https://github.com/Genymobile/scrcpy/pull/4473>