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>
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.
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.
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.
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.
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.
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.
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().
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.
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.