Commit graph

407 commits

Author SHA1 Message Date
Romain Vimont
a8a1da1a00 Disable audio on initialization error
By default, audio is enabled (--no-audio must be explicitly passed to
disable it).

However, some devices may not support audio capture (typically devices
below Android 11, or Android 11 when the shell application is not
foreground on start).

In that case, make the server notify the client to dynamically disable
audio forwarding so that it does not wait indefinitely for an audio
stream.

Also disable audio on unknown codec or missing decoder on the
client-side, for the same reasons.
2023-02-26 22:41:07 +01:00
Romain Vimont
fa85a128da Extract OPUS extradata
For OPUS codec, FFmpeg expects the raw extradata, but MediaCodec wraps
it in some structure.

Fix the config packet to send only the raw extradata.
2023-02-26 22:41:07 +01:00
Romain Vimont
cd099f7a2b Use a streamer to send the audio stream
Send each encoded audio packet using a streamer.
2023-02-26 22:41:07 +01:00
Romain Vimont
20042addd4 Encode recorded audio on the device
For now, the encoded packets are just logged into the console.
2023-02-26 22:41:07 +01:00
Simon Chan
4d39bb9d26 Capture device audio
Create an AudioRecorder to capture the audio source REMOTE_SUBMIX.

For now, the captured packets are just logged into the console.

Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2023-02-26 22:41:07 +01:00
Simon Chan
50d180abf2 Add a new socket for audio stream
When audio is enabled, open a new socket to send the audio stream from
the device to the client.

Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2023-02-26 22:41:07 +01:00
Simon Chan
634ba5d7c4 Add --no-audio option
Audio will be enabled by default (when supported). Add an option to
disable it.

Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2023-02-26 22:41:07 +01:00
Romain Vimont
cadf95cfc4 Use FakeContext for Application instance
This will expose the correct package name and UID to the application
context.
2023-02-26 22:41:07 +01:00
Romain Vimont
13c8209071 Use shell package name for workarounds
For consistency.
2023-02-26 22:41:07 +01:00
Romain Vimont
c21f604f30 Use ROOT_UID from FakeContext
Remove USER_ID from ServiceManager, and replace it by a constant in
FakeContext.

This is the same as android.os.Process.ROOT_UID, but this constant has
been introduced in API 29.
2023-02-26 22:41:07 +01:00
Romain Vimont
db0bf6f34b Use PACKAGE_NAME from FakeContext
Remove duplicated constant.
2023-02-26 22:41:06 +01:00
Romain Vimont
09388f5352 Use AttributionSource from FakeContext
FakeContext already provides an AttributeSource instance.

Co-authored-by: Simon Chan <1330321+yume-chan@users.noreply.github.com>
2023-02-26 22:41:06 +01:00
Simon Chan
2f3092e6b4 Add a fake Android Context
Since scrcpy-server is not an Android application (it's a java
executable), it has no Context.

Some features will require a Context instance to get the package name
and the UID. Add a FakeContext for this purpose.

Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2023-02-26 22:41:06 +01:00
Romain Vimont
0ee541fe26 Improve error message for unknown encoder
The provided encoder name depends on the selected codec. Improve the
error message and the suggestions.
2023-02-26 22:41:06 +01:00
Romain Vimont
58249715ac Rename "codec" variable to "mediaCodec"
This will allow to use "codec" for the Codec type.
2023-02-26 22:41:06 +01:00
Romain Vimont
bbf9eeadf1 Make streamer independent of codec type
Rename VideoStreamer to Streamer, and extract a Codec interface which
will also support audio codecs.
2023-02-26 22:41:06 +01:00
Romain Vimont
3b8bb5feb5 Pass all args to ScreenEncoder constructor
There is no good reason to pass some of them in the constructor and some
others as parameters of the streamScreen() method.
2023-02-26 22:41:06 +01:00
Romain Vimont
fa31aaaba8 Move screen encoder initialization
This prepares further refactors.
2023-02-26 22:41:06 +01:00
Romain Vimont
5b6ae2fef3 Write streamer header from ScreenEncoder
The screen encoder is responsible to write data to the video streamer.
2023-02-26 22:41:06 +01:00
Romain Vimont
bf1a4ae266 Use VideoStreamer directly from ScreenEncoder
The Callbacks interface notifies new packets. But in addition, the
screen encoder will need to write headers on start.

We could add a function onStart(), but for simplicity, just remove the
interface, which brings no value, and call the streamer directly.

Refs 87972e2022
2023-02-26 22:41:06 +01:00
Romain Vimont
a29da81f1a Simplify error handling on socket creation
On any error, all previously opened sockets must be closed.

Handle these errors in a single catch-block. Currently, there are only 2
sockets, but this will simplify even more with more sockets.

Note: this commit is better displayed with --ignore-space-change (-b).
2023-02-26 22:41:06 +01:00
Romain Vimont
82c7752cc4 Do not print stacktraces when unnecessary
User-friendly error messages are printed on specific configuration
exceptions. In that case, do not print the stacktrace.

Also handle the user-friendly error message directly where the error
occurs, and print multiline messages in a single log call, to avoid
confusing interleaving.
2023-02-26 22:41:06 +01:00
Romain Vimont
346145f4bd Silence lint warning about constant in API 29
MediaFormat.MIMETYPE_VIDEO_AV1 has been added in API 29, but it is not
a problem to inline the constant in older versions.
2023-02-26 22:41:06 +01:00
Romain Vimont
d6aff0e5d7 Remove manifest package name
As reported by gradle:

> Setting the namespace via a source AndroidManifest.xml's package
> attribute is deprecated.
>
> Please instead set the namespace (or testNamespace) in the module's
> build.gradle file, as described here:
> https://developer.android.com/studio/build/configure-app-module#set-namespace
2023-02-26 22:41:06 +01:00
Romain Vimont
ebecbe6bc6 Fix inconsistent quotes
The encoder name started with a simple quote but ended with a
double quote. Use a single quote for both.
2023-02-19 16:18:19 +01:00
Romain Vimont
d5dff239c8 Suggest commands with an explicit '=' 2023-02-19 16:18:19 +01:00
Romain Vimont
5cf86ef7ff Move finally-block to fix deadlock on stop
DesktopConnection implements Closeable, so it is implicitly closed after
its try-with-resources block. Closing the DesktopConnection shutdowns
the sockets, so it is necessary in particular to wake up blocking read()
calls from the controller.

But the controller thread was joined before the DesktopConnection was
closed, causing a deadlock. To fix the problem, join the controller
thread only after the DesktopConnection is closed.

Refs 400a1c69b1
2023-02-19 15:59:05 +01:00
Romain Vimont
f4e7085c34 Log non-EPIPE I/O exceptions
On close, the client closes the socket. This wakes up socket blocking
calls on the server-side, by throwing an exception. Since this exception
is expected, it was not logged.

However, other IOExceptions might occur, which must not be ignored. For
that purpose, log only IOException when they are not caused by an EPIPE
error.
2023-02-17 08:33:16 +01:00
Romain Vimont
439a1fd4ed Rename 'uid' to 'scid'
A random identifier is generated to differentiate multiple running
scrcpy instances. Rename it from 'uid' to 'scid' (scrcpy id) not to
confuse it with Linux UID.

Fixes #3729 <https://github.com/Genymobile/scrcpy/issues/3729>
Refs 4315be1648
2023-02-11 09:58:40 +01:00
Romain Vimont
45b2e6db5c Log component stopped in finally clause
The message must be logged even when no exception occurs.
2023-02-10 19:06:17 +01:00
Romain Vimont
400a1c69b1 Join all threads before end of main
Some calls from separate threads may throw exceptions once the main()
method has returned.
2023-02-10 19:04:56 +01:00
Romain Vimont
6524e90c68 Remove unused constant
This line was committed by error.

Refs 3e517cd40e
2023-02-07 23:11:42 +01:00
Romain Vimont
f2dee20a20 Set power mode on all physical displays
Android 10 and above support multiple physical displays. Apply power
mode to all of them.

Fixes #3716 <https://github.com/Genymobile/scrcpy/issues/3716>
2023-02-06 11:07:14 +01:00
Romain Vimont
d2dce51038 Add support for AV1
Add option --codec=av1.

PR #3713 <https://github.com/Genymobile/scrcpy/pull/3713>
2023-02-06 11:00:49 +01:00
Romain Vimont
4342c5637d Add support for H265
Add option --codec=h265.

PR #3713 <https://github.com/Genymobile/scrcpy/pull/3713>
Fixes #3092 <https://github.com/Genymobile/scrcpy/issues/3092>
2023-02-06 11:00:49 +01:00
Romain Vimont
3e517cd40e Add option to select video codec
Introduce the selection mechanism. Alternative codecs will be added in
further commits.

PR #3713 <https://github.com/Genymobile/scrcpy/pull/3713>
2023-02-06 10:58:45 +01:00
Romain Vimont
87972e2022 Extract video streaming to a separate class
ScreenEncoder handled both capture/encoding and sending over the
network.

Move the streaming part to a separate VideoStreamer.
2023-02-03 12:31:28 +01:00
Romain Vimont
3aac74e9e9 Move variable assignment
Computing eof flag is not necessary if rotation changed.
2023-02-03 12:31:28 +01:00
Romain Vimont
1c82c3923d Compute relative PTS on the client-side
The PTS received from MediaCodec are expressed relative to an arbitrary
clock origin. We consider the PTS of the first frame to be 0, and the
PTS of every other frame is relative to this first PTS (note that the
PTS is only used for recording, it is ignored for mirroring).

For simplicity, this relative PTS was computed on the server-side.

To prepare support for multiple stream (video and audio), send the
packet with its original PTS, and handle the PTS offset on the
client-side (by the recorder).

Since we can't know in advance which stream will produce the first
packet with the lowest PTS (a packet received later on one stream may
have a PTS lower than a packet received earlier on another stream),
computing the PTS on the server-side would require unnecessary waiting.
2023-02-03 12:31:28 +01:00
Romain Vimont
36d656e91f Improve workarounds call comments 2023-02-03 12:31:28 +01:00
Romain Vimont
bdbf1f4eb7 Move Workarounds call
Workarounds are not specific to the screen encoder.

Co-authored-by: Simon Chan <1330321+yume-chan@users.noreply.github.com>
2023-02-03 12:31:28 +01:00
Romain Vimont
4177de5880 Do not expose controller threads
The way the controller executes its events asynchronously is an
implementation detail.
2023-02-03 12:31:28 +01:00
Simon Chan
9b286ec8a7 Inject additional ACTION_BUTTON_* events for mouse
On mouse click events:
 - the first button pressed must first generate ACTION_DOWN;
 - all button pressed (including the first one) must generate
   ACTION_BUTTON_PRESS;
 - all button released (including the last one) must generate
   ACTION_BUTTON_RELEASE;
 - the last button released must in addition generate ACTION_UP.

Otherwise, Chrome does not work properly.

Fixes #3635 <https://github.com/Genymobile/scrcpy/issues/3635>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2023-01-30 20:57:54 +01:00
Simon Chan
8c5c55f9e1 Fix mouse pointer state update
If the pointer is a mouse, the pointer is UP only when no buttons are
pressed (not when a button is released, because there might be other
buttons still pressed).

Refs #3635 <https://github.com/Genymobile/scrcpy/issues/3635>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2023-01-30 20:57:54 +01:00
Simon Chan
0afef0c634 Forward action button to device
On click event, only the whole buttons state was passed to the device.
In addition, on ACTION_DOWN and ACTION_UP, pass the button associated to
the action.

Refs #3635 <https://github.com/Genymobile/scrcpy/issues/3635>

Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2023-01-30 20:57:54 +01:00
Romain Vimont
07806ba915 Retry on spurious error
MediaCodec may fail spuriously, typically when stopping an encoding and
starting a new one immediately (for example on device rotation).

In that case, retry a few times, in many cases it should work.

Refs #3693 <https://github.com/Genymobile/scrcpy/issues/3693>
2023-01-30 20:55:51 +01:00
Romain Vimont
a52053421a Extract retry handling
Move the code to downscale and retry on error out of the catch-block.

Refs 26b4104844
2023-01-29 14:49:36 +01:00
Romain Vimont
a9b2697f3e Move local variables declarations
This makes it clear that these local variables are only passed to
setDisplaySurface().
2023-01-27 22:43:16 +01:00
Romain Vimont
b53d2c66e0 Remove useless setSize() method
Inline its content. It makes the logic of internalStreamScreen() more
readable (it reduces the number of indirections).
2023-01-27 22:39:28 +01:00
Romain Vimont
6cccf3ab2a Remove useless configure() method
Inline its single call.
2023-01-27 22:38:37 +01:00