It is incorret to ever call:
streamer.writeDisableStream(...);
after:
streamer.writeAudioHeader();
Move the try-catch block so that it can never happen.
Some devices may provide invalid ranges, causing an
IllegalArgumentException "lower must be less than or equal to upper".
Catch the exception to list the cameras anyway.
Refs #4403 <https://github.com/Genymobile/scrcpy/issues/4403>
Interrupting async processors may require to shutdown the connection to
wake up blocking calls.
Therefore, shutdown the connection first, then join the threads, then
close the connection.
Refs commit 9c08eb79cb
Add --camera-high-speed to enable high frame rate camera capture. If
the option is enabled, then --camera-fps is mandatory.
PR #4213 <https://github.com/Genymobile/scrcpy/pull/4213>
Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
Add a new option for specifying the camera frame rate.
By default, Android's default frame rate (30 fps) is used.
PR #4213 <https://github.com/Genymobile/scrcpy/pull/4213>
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
In addition to --camera-size to specify an explicit size, make it
possible to select the camera size automatically, respecting the maximum
size (already used for display mirroring) and an aspect ratio.
For example, "scrcpy --video-source=camera" followed by:
- (no additional arguments)
: mirrors at the maximum size, any a-r
- -m1920
: only consider valid sizes having both dimensions not above 1920
- --camera-ar=4:3
: only consider valid sizes having an aspect ratio of 4:3 (+/- 10%)
- -m2048 --camera-ar=1.6
: only consider valid sizes having both dimensions not above 2048
and an aspect ratio of 1.6 (+/- 10%)
PR #4213 <https://github.com/Genymobile/scrcpy/pull/4213>
Co-authored-by: Simon Chan <1330321+yume-chan@users.noreply.github.com>
Add an option to select the camera by its lens facing (front, back or
external).
PR #4213 <https://github.com/Genymobile/scrcpy/pull/4213>
Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
Extract an interface SurfaceCapture from ScreenEncoder, representing a
video source which can be rendered to a Surface for encoding.
Split ScreenEncoder into:
- ScreenCapture, implementing SurfaceCapture to capture the device
screen,
- SurfaceEncoder, to encode any SurfaceCapture.
This separation prepares the introduction of another SurfaceCapture
implementation to capture the camera instead of the device screen.
PR #4213 <https://github.com/Genymobile/scrcpy/pull/4213>
Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
By default, the Java process exits when all non-daemon threads are
terminated.
The Android SDK might start some non-daemon threads internally,
preventing the scrcpy server to exit in some cases.
So force the process to exit explicitly.
PR #4213 <https://github.com/Genymobile/scrcpy/pull/4213>
The option is named "display id" everywhere.
This will be consistent with --camera-id (there will be many camera
options, so an option --camera would be confusing).
PR #4213 <https://github.com/Genymobile/scrcpy/pull/4213>
Some devices (Meizu) assume that the video encoding thread has a
Looper. By moving video encoding to a separate thread, commit
feab87053a broke this assumption.
Call Looper.prepare() from this thread to fix the problem.
Fixes#4143 <https://github.com/Genymobile/scrcpy/issues/4143>
In forward mode, the dummy byte must be written immediately after the
first accept(), otherwise the client will wait indefinitely, causing a
deadlock (or a timeout).
Regression introduced by 8c650e53cd.
Audio did not work on Honor devices.
To make it work, a system context must be set as a base context of
FakeContext (so that a PackageManager is available), and a current
Application and ActivityThread must be set.
These workarounds must not be applied for all devices, because they
might cause other issues.
Fixes#4015 <https://github.com/Genymobile/scrcpy/issues/4015>
Refs #3085 <https://github.com/Genymobile/scrcpy/issues/3805>
Co-authored-by: Simon Chan <1330321+yume-chan@users.noreply.github.com>
The flag is used to reset the capture (restart the encoding) on rotation
change. It will also be used for other events (on folding change), so
rename it.
PR #3979 <https://github.com/Genymobile/scrcpy/pull/3979>
Contrary to the other tasks (controller and audio capture/encoding), the
screen encoder was executed synchronously. As a consequence,
scrcpy-server could not terminate until the screen encoder returned.
Convert it to an async processor. This allows to terminate on controller
error, and this paves the way to disable video mirroring.
PR #3978 <https://github.com/Genymobile/scrcpy/pull/3978>
The async processors use the socket file descriptors from the
connection. Therefore, the connection must not be closed before all
async processor threads are joined.
PR #3978 <https://github.com/Genymobile/scrcpy/pull/3978>
The code to start audio capture is more complicated for Android 11
(launch a fake popup, wait, make several attempts, close the shell
package).
Use a distinct code path specific to Android 11.
On Android 11, a fake popup must be briefly opened to make the system
think that the shell app is in the foreground so that audio may be
recorded.
Making the shell app foreground may take some time depending on the
device, so make 3 attempts, waiting 100ms before each.
Fixes#3796 <https://github.com/Genymobile/scrcpy/issues/3796>
There were several workarounds applied in a single method. Some of them
are specific to Meizu phones, but cause issues on other devices.
Split the method to be able to only fill the app context for audio
capture without applying the Meizu workarounds.
Fixes#3801 <https://github.com/Genymobile/scrcpy/issues/3801>
On initial connection, scrcpy sent some device metadata:
- the device name (to be used as window title)
- the initial video size (before any frame or even SPS/PPS)
But it is better to provide the initial video size as part as the video
stream, so that it can be demuxed and exposed via AVCodecContext to
sinks.
This avoids to pass an explicit "initial frame size" for the screen, the
recorder and the v4l2 sink.
All server logs were printed to stdout, while all client logs were
printed to stderr.
Instead, use stderr for warnings and errors, stdout for the others:
- stdout: verbose, debug, info
- stderr: warn, error
System.out.println() first prints the message, then the new line.
Between these two calls, the client might print a message, breaking
formatting.
Instead, call System.out.print() with '\n' appended to the message.
On the server side, several components are started, stopped and joined.
Extract an interface to handle them generically.
This will help to support both encoded and raw audio stream, because
they will be two different concrete components, but implementing the
same interface.
PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
On Android 11, it is possible to start the capture only when the running
app is in foreground. But scrcpy is not an app, it's a Java application
started from shell.
As a workaround, start an existing Android shell existing activity just
to start the capture, then close it immediately.
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>
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>