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