Commit Graph

398 Commits

Author SHA1 Message Date
Romain Vimont
a1b97fbfaa 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-18 19:10:28 +01:00
Romain Vimont
5d5a1d6888 Use a streamer to send the audio stream
Send each encoded audio packet using a streamer.
2023-02-18 19:10:28 +01:00
Romain Vimont
c19fefbcbd Encode recorded audio in OPUS on the device
For now, the encoded packets are just logged in the console.
2023-02-18 19:10:28 +01:00
Simon Chan
bc0f51023e Capture device audio
Create an AudioRecorder to capture the audio source REMOTE_SUBMIX.

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

Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2023-02-18 19:10:28 +01:00
Simon Chan
3a8a7d5ba8 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-18 19:10:27 +01:00
Simon Chan
1fe2afb4df 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-18 19:10:27 +01:00
Romain Vimont
47d0c189ec Use FakeContext for Application instance
This will expose the correct package name and UID to the application
context.
2023-02-18 19:10:27 +01:00
Romain Vimont
c76264c149 Use shell package name for workarounds
For consistency.
2023-02-18 19:10:27 +01:00
Romain Vimont
be09e65fa4 Use PACKAGE_NAME from FakeContext
Remove duplicated constant.
2023-02-18 19:10:27 +01:00
Romain Vimont
de8a9a4045 Use AttributionSource from FakeContext
FakeContext already provides an AttributeSource instance.

Co-authored-by: Simon Chan <1330321+yume-chan@users.noreply.github.com>
2023-02-18 19:10:27 +01:00
Simon Chan
4e47d78f30 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-18 19:10:27 +01:00
Romain Vimont
0873b08c85 Use Process.ROOT_UID
Replace ServiceManager.USER_ID by existing constant Process.ROOT_UID.
2023-02-18 19:10:27 +01:00
Romain Vimont
83c64d918b Make streamer independent of codec type
Rename VideoStreamer to Streamer, and extract a Codec interface which
will also support audio codecs.
2023-02-18 19:10:26 +01:00
Romain Vimont
aedd90a955 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-18 19:10:26 +01:00
Romain Vimont
e153f4657c Move screen encoder initialization
This prepares further refactors.
2023-02-18 19:10:26 +01:00
Romain Vimont
dd2959b0cb Write streamer header from ScreenEncoder
The screen encoder is responsible to write data to the video streamer.
2023-02-18 19:10:26 +01:00
Romain Vimont
6118c2b4cd 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-18 19:10:26 +01:00
Romain Vimont
fad8c68090 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-18 19:10:26 +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
Romain Vimont
52f85fd6f1 Keep the same MediaCodec instance across sessions
Calling codec.reset() is sufficient.
2023-01-27 22:31:09 +01:00
Romain Vimont
91c69ad95c Remove useless destroyDisplay() method
The method made exactly one simple call. Just make the call directly.
2023-01-27 22:28:11 +01:00
Romain Vimont
75d7c01a0c Keep the same display binder across sessions
Do not destroy/recreate the display when starting a new encoding session
(on device rotation for example).
2023-01-27 22:26:01 +01:00
Romain Vimont
74d32e612d Terminate loop explicitly on interrupted
Make explicit that the loop terminates when the current thread is
interrupted.
2023-01-27 22:20:35 +01:00
Romain Vimont
bdba554118 Use Java lambdas where possible 2023-01-27 22:16:36 +01:00
Romain Vimont
234ad7ee78 Support Java lambdas in build_without_gradle.sh
Building Java source code using lambdas requires core-lambda-stubs.jar.

Refs #3657 <https://github.com/Genymobile/scrcpy/issues/3657>
2023-01-27 22:08:25 +01:00
Romain Vimont
8cbbcc939f Add missing final modifiers 2023-01-27 22:08:17 +01:00
Romain Vimont
b22810b17c Use try-with-resources
Replace an explicit try-finally by a try-with-resources block.
2023-01-27 21:59:26 +01:00
Romain Vimont
4315be1648 Use random name for device socket
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").
2023-01-27 21:51:59 +01:00