Play the decoded audio using SDL.
The audio player frame sink receives the audio frames, resample them
and write them to a byte buffer (introduced by this commit).
On SDL audio callback (from an internal SDL thread), copy samples from
this byte buffer to the SDL audio buffer.
The byte buffer is protected by the SDL_AudioDeviceLock(), but it has
been designed so that the producer and the consumer may write and read
in parallel, provided that they don't access the same slices of the
ring-buffer buffer.
PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
Co-authored-by: Simon Chan <1330321+yume-chan@users.noreply.github.com>
A delay buffer delayed all the frames except the first one, to open the
scrcpy window immediately and get a picture.
Make this feature optional, so that the delay buffer might also be used
for audio (especially for simulating a high delay for debugging).
PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
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>
By default, scrcpy mirrors only the video when audio capture fails on
the device. Add an option to force scrcpy to fail if audio is enabled
but does not work.
PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
When audio capture fails on the device, scrcpy continues mirroring the
video stream. This allows to enable audio by default only when
supported.
However, if an audio configuration occurs (for example the user
explicitly selected an unknown audio encoder), this must be treated as
an error and scrcpy must exit.
PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
Audio will be enabled by default (when supported). Add an option to
disable it.
PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
The recorder opened the target file from the packet sink open()
callback, called by the demuxer. Only then the recorder thread was
started.
One golden rule for the recorder is to never block the demuxer for I/O,
because it would impact mirroring. This rule is respected on recording
packets, but not for the initial recorder opening.
Therefore, start the recorder thread from sc_recorder_init(), open the
file immediately from the recorder thread, then make it wait for the
stream to start (on packet sink open()).
Now that the recorder can report errors directly (rather than making the
demuxer call fail), it is possible to report file opening error even
before the packet sink is open.
Stop scrcpy on recorder errors.
It was previously indirectly stopped by the demuxer, which failed to
push packets to a recorder in error. Report it directly instead:
- it avoids to wait for the next demuxer call;
- it will allow to open the target file from a separate thread and stop
immediately on any I/O error.
For the initial connection between the device and the computer, an adb
tunnel is established (with "adb reverse" or "adb forward").
The device-side of the tunnel is a local socket having the hard-coded
name "scrcpy". This may cause issues when several scrcpy instances are
started in a few seconds for the same device, since they will try to
bind the same name.
To avoid conflicts, make the client generate a random UID, and append
this UID to the local socket name ("scrcpy_01234567").
We must distinguish 3 cases for await_for_server():
- an error occurred
- no error occurred, the device is connected
- no error occurred, the device is not connected (user requested to
quit)
For this purpose, use an additional output parameter to indicate if the
device is connected (only set when no error occurs).
Refs #3085 <https://github.com/Genymobile/scrcpy/pull/3085>
If several devices are connected (as listed by `adb devices`), it was
necessary to provide the explicit serial via -s/--serial.
If only one device is connected via USB (respectively, via TCP/IP), it
might be convenient to select it automatically. For this purpose, two
new options are introduced:
- -d/--select-usb: select the single device connected over USB
- -e/--select-tcpip: select the single device connected over TCP/IP
PR #3005 <https://github.com/Genymobile/scrcpy/pull/3005>
Before starting the server, the actual device serial (possibly its
ip:port if it's over TCP/IP) must be known.
A serial might be requested via -s/--serial (stored in the
sc_server_params), but the actual serial may change afterwards:
- if none is provided, then it is retrieved with "adb get-serialno";
- if --tcpip is requested, then the final serial will be the target
ip:port.
The requested serial was overwritten by the actual serial in the
sc_server_params struct, which was a bit hacky.
Instead, store a separate serial field in sc_server (and rename the one
from sc_server_params to "req_serial" to avoid confusion).