Headers seem to be a bit different in Apple land and you need to include
stddef.h explicitly to the NULL declaration.
This also makes the code a bit more correct, as stddef.h is the header
in the C standard that defines NULL
(https://en.cppreference.com/w/cpp/header/cstddef).
We need several FIFO queues (a queue of packets, a queue of messages,
etc.).
Some of them are implemented using cbuf, a generic circular buffer. But
for recording, we need to store the packets in an unbounded queue until
they are written, so the queue was implemented manually.
Create a generic implementation (using macros) to avoid reimplementing
it every time.
The record file was written from the stream thread. As a consequence,
any blocking I/O to write the file delayed the decoder.
For maximum performance even when recording is enabled, send
(refcounted) packets to a separate recording thread.
To packetize the H.264 raw stream, av_parser_parse2() (called by
av_read_frame()) knows that it has received a full frame only after it
has received some data for the next frame. As a consequence, the client
always waited until the next frame before sending the current frame to
the decoder!
On the device side, we know packets boundaries. To reduce latency,
make the device always transmit the "frame meta" to packetize the stream
manually (it was already implemented to send PTS, but only enabled on
recording).
On the client side, replace av_read_frame() by manual packetizing and
parsing.
<https://stackoverflow.com/questions/50682518/replacing-av-read-frame-to-reduce-delay>
<https://trac.ffmpeg.org/ticket/3354>
If --no-control is set, then the controller is not initialized (both in
the client and the server), so it is not possible to control the device
to turn its screen off.
See <https://github.com/Genymobile/scrcpy/issues/608>.
In portable builds, scrcpy-server.jar was supposed to be present in the
current directory, so in practice it worked only if scrcpy was launched
from its own directory.
Instead, find the absolute path of the executable and build a suitable
path to use scrcpy-server.jar from the same directory.
There was already utf8_to_wide_char(), used to correctly execute
commands on Windows.
Add the reverse converter: utf8_from_wide_char(). We will need it to
build the scrcpy-server path based on the executable directory.
To create a portable build (with scrcpy-server.jar accessible from the
scrcpy directory), replace OVERRIDE_SERVER_PATH by a simple compilation
flag: PORTABLE.
This paves the way to use more complex rules to determine the path of
scrcpy-server.jar in portable builds.
On socket disconnection, on Linux, recv() returns -1 and errno is set.
But on Windows, errno is 0.
In that case, AVERROR(errno) == 0, leading to the warning:
> Invalid return value 0 for stream protocol
To avoid the problem, if errno is 0, return AVERROR_EOF.
Ref: commit 2876463d39
The FPS counter was called only on new frames, so it could not print
values regularly, especially when there are very few FPS (when the
device surface does not change).
To the extreme, it was never able to display 0 fps.
Add a separate thread to print framerate every second.
Only keep "turn device screen off" and POWER button.
After we turn the device screen off (with Ctrl+o), turning it back on
does not always work, and leaves the device in a weird state, where even
the power button may not be sufficient:
<https://github.com/Genymobile/scrcpy/issues/175#issuecomment-497946596>
This is not an acceptable behavior, so disable the shortcut to turn the
physical device screen on. We can use the POWER button (or Ctrl+p)
instead.
The condition "event->type == SDL_KEYDOWN" and the variable
input_manager->controller are used many times. Replace them by local
variables to reduce verbosity.
Add two shortcuts:
- Ctrl+o to turn the device screen off while mirroring
- Ctrl+Shift+o to turn it back on
On power on (either via the POWER key or BACK while screen is off), both
the device screen and the mirror are turned on.
<https://github.com/Genymobile/scrcpy/issues/175>
Use the same variable name in functions declaration and definition.
Signed-off-by: Yu-Chen Lin <npes87184@gmail.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
After the recent refactorings, a "control event" is not necessarily an
"event" (it may be a "command"). Similarly, the unique "device event"
used to send the device clipboard content is more a "reponse" to the
request from the client than an "event".
Rename both to "message", and rename the message types to better
describe their intent.
It was already possible to _paste_ (with Ctrl+v) the content of the
computer clipboard on the device. Technically, it injects a sequence of
events to generate the text.
Add a new feature (Ctrl+Shift+v) to copy to the device clipboard
instead, without injecting the content. Contrary to events injection,
this preserves the UTF-8 content exactly, so the text is not broken by
special characters.
<https://github.com/Genymobile/scrcpy/issues/413>
On Ctrl+C:
- the client sends a GET_CLIPBOARD command to the device;
- the device retrieve its current clipboard text and sends it in a
GET_CLIPBOARD device event;
- the client sets this text as the system clipboard text, so that it
can be pasted in another application.
Fixes <https://github.com/Genymobile/scrcpy/issues/145>
The socket used the device-to-computer direction to stream the video and
the computer-to-device direction to send control events.
Some features, like copy-paste from device to computer, require to send
non-video data from the device to the computer.
To make them possible, use two sockets:
- one for streaming the video from the device to the client;
- one for control/events in both directions.
A string is serialized as a length (2 bytes) followed by the string data
(non nul-terminated).
For now, it is used only once, but we will need to serialize strings in
other events.
Several commands were grouped under the same event type "command", with
a separate field to indicate the actual command.
Move these commands at the same level as other control events. It will
allow to implement commands with arguments.
The cleanup is not linear: for example, the server must be stopped and
its sockets must be shutdown after the stream and controller are stopped
(so that they don't continue processing garbage), but before they are
joined, to avoid a deadlock if they are blocked on a socket read.
Simplify the spaghetti-cleanup by keeping trace of initialization at
runtime.
Compositor bypass is meant for fullscreen games consuming lots of GPU
resources. For a light app that will usually be windowed, this only
causes unnecessary compositor suspends, especially visible (and
annoying) with complying window manager like KWin.
Signed-off-by: Romain Vimont <rom@rom1v.com>