Commit Graph

670 Commits

Author SHA1 Message Date
Romain Vimont 2356a869f4 Revert "Do not recreate display on every rotation"
This reverts commit 5eaf072a85.
2024-11-16 14:56:17 +01:00
Romain Vimont 1ccc7b201d Add --angle
Add an option to rotate the video content by a custom angle.
2024-11-16 12:14:35 +01:00
Romain Vimont 5eaf072a85 Do not recreate display on every rotation
This semantically reverts 7e3b935932.

The issue seems to be fixed if setSurface() is called before resize() on
the virtual display.

Refs #4840 <https://github.com/Genymobile/scrcpy/pull/4840>
2024-11-16 12:14:35 +01:00
Romain Vimont 5894a76a0a Use natural device orientation for --new-display
If no size is provided with --new-display, the main display size is
used. But the actual size depended on the current device orientation.

To make it deterministic, use the size of the natural device orientation
(portrait for phones, landscape for tablets).
2024-11-16 12:14:35 +01:00
Romain Vimont a3fbac6d88 Improve mismatching event size warning
Include both the event size and the current size in the warning message.
2024-11-16 12:14:35 +01:00
Romain Vimont 746217ba2c Apply filters to virtual display capture 2024-11-16 12:14:35 +01:00
Romain Vimont db66d7a98b Apply filters to camera capture 2024-11-16 12:14:35 +01:00
Romain Vimont fe0fc0de37 Add --capture-orientation
Deprecate --lock-video-orientation in favor of a more general option
--capture-orientation, which supports all possible orientations
(0, 90, 180, 270, flip0, flip90, flip180, flip270), and a "locked" flag
via a '@' prefix.

All the old "locked video orientations" are supported:
 - --lock-video-orientation      ->  --capture-orientation=@
 - --lock-video-orientation=0    ->  --capture-orientation=@0
 - --lock-video-orientation=90   ->  --capture-orientation=@90
 - --lock-video-orientation=180  ->  --capture-orientation=@180
 - --lock-video-orientation=270  ->  --capture-orientation=@270

In addition, --capture-orientation can rotate/flip the display without
locking, so that it follows the physical device rotation.

For example:

    scrcpy --capture-orientation=flip90

always flips and rotates the capture by 90° clockwise.

The arguments are consistent with --orientation (which provides a
separate client-side orientation).
2024-11-16 12:14:34 +01:00
Romain Vimont f51636164a Handle virtual display rotation 2024-11-16 11:28:22 +01:00
Romain Vimont bf2c8cac9f Extract DisplayCapture
This will allow to share common code between ScreenCapture and
NewDisplayCapture.
2024-11-16 11:28:22 +01:00
Romain Vimont 26d66a7c28 Reimplement lock orientation using transforms
Reimplement the --lock-video-orientation feature using affine
transforms.
2024-11-16 11:28:22 +01:00
Romain Vimont 58c73504d4 Reimplement crop using transforms
Reimplement the --crop feature using affine transforms.
2024-11-16 11:28:22 +01:00
Romain Vimont 3a0f977e5b Ignore signalEndOfStream() error
This may be called at any time to interrupt the current encoding,
including when MediaCodec is in an expected state.
2024-11-16 11:28:22 +01:00
Romain Vimont 292af180c0 Move mediaCodec.stop() to finally block
This will allow to stop MediaCodec only after clean ups of other
components which must be performed before stopping MediaCodec.
2024-11-16 11:28:22 +01:00
Romain Vimont c0056637e9 Make PositionMapper use affine transforms
This will allow to apply transformations performed by video filters.
2024-11-16 11:28:22 +01:00
Romain Vimont b05bfa73b1 Temporarily ignore lock video orientation and crop
Get rid of old code implementing --lock-video-orientation and --crop
features on the device side.

They will be reimplemented differently.
2024-11-16 11:28:22 +01:00
Romain Vimont c33d72ea21 Split computeVideoSize() into limit() and round8()
Expose two methods on Size directly:
 - limit() to downscale a size;
 - round8() to round both dimensions to multiples of 8.

This will allow to remove ScreenInfo completely.
2024-11-16 11:28:22 +01:00
Romain Vimont 8dbdd73b81 Revert "Disable broken options on Android 14"
This reverts commit d62fa8880e.

These options will be reimplemented differently.
2024-11-16 11:28:22 +01:00
Romain Vimont 15fc55657f Add on-device OpenGL video filter architecture 2024-11-16 11:28:20 +01:00
Romain Vimont bd9d93194b Pass Options instance directly
Many constructors take a lot of parameters copied from Options. For
simplicity, just pass the Options instance.
2024-11-15 20:16:04 +01:00
Romain Vimont 794595e3f0 Set displayId to NONE in Options on new display
If a new display is set, force options.getDisplayId() to return
Device.DISPLAY_ID_NONE, to avoid any confusion between a local displayId
and options.getDisplayId().
2024-11-15 20:16:04 +01:00
Romain Vimont 5e10c37f02 Define all DisplayManager flags locally
For consistency.
2024-11-15 20:16:04 +01:00
Romain Vimont 0e399b65bd Remove [] around app package names
This simplifies copy-pasting from the result of:

    scrcpy --list-apps
2024-11-15 20:16:04 +01:00
Romain Vimont 2337f524d1 Improve error message on unknown camera id
If the camera id is explicitly provided (via --camera-id), report a
user-friendly error if no camera with this id is found.
2024-11-15 20:16:04 +01:00
Romain Vimont df74cceb6f Use camera prepare() step
For consistency with screen capture.

Refs b60e174780
2024-11-15 20:16:04 +01:00
Simon Chan 91373d906b Add FakeContext.getContentResolver()
This avoids the following error on some devices:

    Given calling package android does not match caller's uid 2000

Refs #4639 comment <https://github.com/Genymobile/scrcpy/issues/4639#issuecomment-2466081589>
Fixes #4639 <https://github.com/Genymobile/scrcpy/issues/4639>
PR #5476 <https://github.com/Genymobile/scrcpy/pull/5476>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2024-11-14 10:29:03 +01:00
Simon Chan c0e2e27cf9 Force javac to use UTF-8
The source files are encoded in UTF-8.

Refs <https://github.com/Genymobile/scrcpy/issues/4639#issuecomment-2467206100>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2024-11-11 09:00:40 +01:00
Romain Vimont eff5b4b219 Add --screen-off-timeout
Change the Android "screen off timeout" (the idle delay before the
screen automatically turns off) and restore the initial value on
exit.

PR #5447 <https://github.com/Genymobile/scrcpy/pull/5447>
2024-11-09 10:26:59 +01:00
Romain Vimont d3db9c4065 Refactor clean up configuration to simplify
All options were configured dynamically by sending a single byte to an
output stream. But in practice, only the power mode must be changed
dynamically, the others are configured once on start.

For simplicity, pass the value of static options as command line
arguments, and handle dynamic options in a loop only from a separate
thread once the clean up process is started.

This will allow to easily add cleanup options with values which do not
fit in 1 byte.

Also handle the clean up thread (and the loading of initial settings
values) from the CleanUp class, to expose a simpler clean up API.

Refs 9efa162949
PR #5447 <https://github.com/Genymobile/scrcpy/pull/5447>
2024-11-09 10:26:43 +01:00
Romain Vimont 104195fc3b Add shortcut to reset video capture/encoding
Reset video capture/encoding on MOD+Shift+r.

Like on device rotation, this starts a new encoding session which
produces a video stream starting by a key frame.

PR #5432 <https://github.com/Genymobile/scrcpy/pull/5432>
2024-11-03 19:31:02 +01:00
Romain Vimont 9958302e6f Interrupt MediaCodec blocking call on reset
When the MediaCodec input is a Surface, no EOS (end-of-stream) will
never occur automatically: it may only be triggered manually by
MediaCodec.signalEndOfInputStream().

Use this signal to interrupt the blocking call to dequeueOutputBuffer()
immediately on reset, without waiting for the next frame to be dequeued.

PR #5432 <https://github.com/Genymobile/scrcpy/pull/5432>
2024-11-03 19:27:11 +01:00
Romain Vimont 69b836930a Handle capture reset via listener
When the capture source becomes "invalid" (because the display size
changes for example), a reset request is performed to restart the
encoder.

The reset state was stored in SurfaceCapture. The capture implementation
set the flag, and the encoder consumed it.

However, this mechanism did not allow a reset request to _interrupt_ the
encoder, which may be waiting on a blocking call (until a new frame is
produced).

To be able to interrupt the encoder, a reset request must not only set a
flag, but run a callback provided by the encoder. For that purpose,
introduce the CaptureListener interface, which is notified by the
SurfaceCapture implementation whenever the capture is invalidated.

For now, the listener implementation just set a flag as before, so the
behavior is unchanged. It lays the groundwork for the next commits.

PR #5432 <https://github.com/Genymobile/scrcpy/pull/5432>
2024-11-03 19:26:55 +01:00
Romain Vimont 790ea5e58c Check screen on for current displayId
Since Android 14, the "screen on" state can be checked per-display.

Refs <956f4084df%5E!/#F17>
PR #5442 <https://github.com/Genymobile/scrcpy/pull/5442>
2024-11-03 19:10:44 +01:00
Romain Vimont 1270997f6b Remove useless assignment
The local variable virtualDisplayId was already initialized to the exact
same value.
2024-11-03 19:02:57 +01:00
Romain Vimont c905fbba8d Fix indentation 2024-11-03 19:02:37 +01:00
Romain Vimont f08a6d86c5 Power on the device only for main display
Power on the device on start only if scrcpy is mirroring the main
display.
2024-11-02 18:51:05 +01:00
Romain Vimont 3ac4b64461 Register rotation watcher for non-main displays
While moving code, commit 874eaec487 added
a condition `if (displayId == 0)` to register a rotation watcher,
without good reasons.

This condition was kept when the rotation watcher was moved to a
fallback in e26bdb07a2.

Note: use `git show -b` to show this commit ignoring whitespace changes.

Refs #5428 <https://github.com/Genymobile/scrcpy/issues/5428>
2024-11-02 18:49:08 +01:00
Romain Vimont c7378f4dc8 Extract setting display power to a separate method
For consistency with the other actions.
2024-10-31 22:49:03 +01:00
Romain Vimont e26bdb07a2 Listen to display changed events
Replace RotationWatcher and DisplayFoldListener by a single
DisplayListener, which is notified whenever the display size or dpi
changes.

However, the DisplayListener mechanism is broken in the first versions
of Android 14 (it is fixed in android-14.0.0_r29 by commit [1]), so
continue to use the old mechanism specifically for Android 14 (where
DisplayListener may be broken), until we receive the first
"display changed" event (which proves that it works).

[1]: <5653c6b587%5E%21/>

Fixes #161 <https://github.com/Genymobile/scrcpy/issues/161>
Fixes #1918 <https://github.com/Genymobile/scrcpy/issues/1918>
Fixes #4152 <https://github.com/Genymobile/scrcpy/issues/4152>
Fixes #5362 comment <https://github.com/Genymobile/scrcpy/issues/5362#issuecomment-2416219316>
Refs #4469 <https://github.com/Genymobile/scrcpy/pull/4469>
PR #5415 <https://github.com/Genymobile/scrcpy/pull/5415>

Co-authored-by: Simon Chan <1330321+yume-chan@users.noreply.github.com>
2024-10-31 20:12:23 +01:00
Romain Vimont 04a3e6fb06 Consume reset request on encoding start
If a reset request is pending when a new encoding starts, then it is
implicitly fulfilled.

PR #5415 <https://github.com/Genymobile/scrcpy/pull/5415>
2024-10-31 20:12:23 +01:00
Romain Vimont d62fa8880e Disable broken options on Android 14
The options --lock-video-orientation and --crop are broken since Android
14. Hopefully, they will be reimplemented differently.

Meanwhile, when running Android >= 14, fail with an error to prevent
incorrect behavior.

Refs #4011 <https://github.com/Genymobile/scrcpy/issues/4011>
Refs #4162 <https://github.com/Genymobile/scrcpy/issues/4162>
PR #5417 <https://github.com/Genymobile/scrcpy/pull/5417>
2024-10-31 19:55:47 +01:00
Romain Vimont 58ba00fa06 Adapt "turn screen off" for Android 15
Android 15 introduced an easy way to set the display power:
<fd8b5efc7f%5E!/#F17>

Refs #3927 <https://github.com/Genymobile/scrcpy/issues/3927>
Refs <https://issuetracker.google.com/issues/303565669>
PR #5418 <https://github.com/Genymobile/scrcpy/pull/5418>
2024-10-30 19:38:35 +01:00
Romain Vimont 569c37cec1 Disable display power for virtual displays
If displayId == Device.DISPLAY_ID_NONE, then the display is virtual: its
power mode cannot be changed.

PR #5418 <https://github.com/Genymobile/scrcpy/pull/5418>
2024-10-30 19:38:07 +01:00
Romain Vimont 58a0fbbf2e Refactor display power mode
Accept a single boolean "on" rather than a "mode" (which, in practice,
could only take 2 values: NORMAL and OFF).

Also rename "screen power mode" to "display power".

PR #5418 <https://github.com/Genymobile/scrcpy/pull/5418>
2024-10-30 19:38:04 +01:00
Romain Vimont acff5b005c Add more details to --list-encoders output
Add more information about each codec (hw/sw, vendor, alias).

Before:

    [server] INFO: List of video encoders:
        --video-codec=h264 --video-encoder=c2.exynos.h264.encoder
        --video-codec=h264 --video-encoder=c2.android.avc.encoder
        --video-codec=h264 --video-encoder=OMX.google.h264.encoder
        --video-codec=h265 --video-encoder=c2.exynos.hevc.encoder
        --video-codec=h265 --video-encoder=c2.android.hevc.encoder
        --video-codec=av1 --video-encoder=c2.google.av1.encoder
        --video-codec=av1 --video-encoder=c2.android.av1.encoder
    // audio encoders omitted

After:

    [server] INFO: List of video encoders:
        --video-codec=h264 --video-encoder=c2.exynos.h264.encoder         (hw) [vendor]
        --video-codec=h264 --video-encoder=c2.android.avc.encoder         (sw)
        --video-codec=h264 --video-encoder=OMX.google.h264.encoder        (sw) (alias for c2.android.avc.encoder)
        --video-codec=h265 --video-encoder=c2.exynos.hevc.encoder         (hw) [vendor]
        --video-codec=h265 --video-encoder=c2.android.hevc.encoder        (sw)
        --video-codec=av1 --video-encoder=c2.google.av1.encoder           (hw) [vendor]
        --video-codec=av1 --video-encoder=c2.android.av1.encoder          (sw)
    // audio encoders omitted

PR #5416 <https://github.com/Genymobile/scrcpy/pull/5416>
2024-10-30 18:51:00 +01:00
Romain Vimont 5474ae6bd6 Factorize codec info listing
Make the listing of video and audio encoders share the same code.

PR #5416 <https://github.com/Genymobile/scrcpy/pull/5416>
2024-10-30 18:50:47 +01:00
Romain Vimont 566b5be0f6 Add option to start an app by its name
By adding the '?' prefix, the app is searched by its name instead of its
package name (retrieving app names on the device may take some time):

    scrcpy --start-app=?firefox

An app matches if its label starts with the given name,
case-insensitive.

If '+' is also passed to force-stop the app before starting, then the
prefixes must be in that order:

    scrcpy --start-app=+?firefox

PR #5370 <https://github.com/Genymobile/scrcpy/pull/5370>
2024-10-28 18:18:36 +01:00
Romain Vimont dd20efa41c Add option to force-stop app before starting
The previous commit introduced:

    scrcpy --start-app=name

By adding a '+' prefix, the app is stopped beforehand:

    scrcpy --start-app=+name

This may be useful to start a fresh app on a new virtual display:

    scrcpy --new-display --start-app=+org.mozilla.firefox

PR #5370 <https://github.com/Genymobile/scrcpy/pull/5370>
2024-10-28 18:18:36 +01:00
Romain Vimont 13ce277e1f Add --start-app
Add a command line option --start-app=name to start an Android app by
its package name. For example:

    scrcpy --start-app=org.mozilla.firefox

The app will be started on the correct target display:

    scrcpy --new-display=1920x1080 --start-app=org.videolan.vlc

PR #5370 <https://github.com/Genymobile/scrcpy/pull/5370>

Co-authored-by: Simon Chan <1330321+yume-chan@users.noreply.github.com>
2024-10-28 18:18:36 +01:00
Romain Vimont 9c9d92fb1c Add --list-apps
Add an option to list all apps installed on the device:

    scrcpy --list-apps

PR #5370 <https://github.com/Genymobile/scrcpy/pull/5370>
2024-10-28 18:18:36 +01:00