diff --git a/FAQ.md b/FAQ.md
index e6c3c94d..9b22c447 100644
--- a/FAQ.md
+++ b/FAQ.md
@@ -164,32 +164,6 @@ keyboard][hid] (HID).
## Client issues
-### The quality is low
-
-If the definition of your client window is smaller than that of your device
-screen, then you might get poor quality, especially visible on text (see [#40]).
-
-[#40]: https://github.com/Genymobile/scrcpy/issues/40
-
-This problem should be fixed in scrcpy v1.22: **update to the latest version**.
-
-On older versions, you must configure the [scaling behavior]:
-
-> `scrcpy.exe` > Properties > Compatibility > Change high DPI settings >
-> Override high DPI scaling behavior > Scaling performed by: _Application_.
-
-[scaling behavior]: https://github.com/Genymobile/scrcpy/issues/40#issuecomment-424466723
-
-Also, to improve downscaling quality, trilinear filtering is enabled
-automatically if the renderer is OpenGL and if it supports mipmapping.
-
-On Windows, you might want to force OpenGL to enable mipmapping:
-
-```
-scrcpy --render-driver=opengl
-```
-
-
### Issue with Wayland
By default, SDL uses x11 on Linux. The [video driver] can be changed via the
@@ -224,102 +198,15 @@ As a workaround, [disable "Block compositing"][kwin].
### Exception
-There may be many reasons. One common cause is that the hardware encoder of your
-device is not able to encode at the given definition:
-
-> ```
-> ERROR: Exception on thread Thread[main,5,main]
-> android.media.MediaCodec$CodecException: Error 0xfffffc0e
-> ...
-> Exit due to uncaughtException in main thread:
-> ERROR: Could not open video stream
-> INFO: Initial texture: 1080x2336
-> ```
-
-or
-
-> ```
-> ERROR: Exception on thread Thread[main,5,main]
-> java.lang.IllegalStateException
-> at android.media.MediaCodec.native_dequeueOutputBuffer(Native Method)
-> ```
-
-Just try with a lower definition:
+If you get any exception related to `MediaCodec`:
```
-scrcpy -m 1920
-scrcpy -m 1024
-scrcpy -m 800
+ERROR: Exception on thread Thread[main,5,main]
+java.lang.IllegalStateException
+ at android.media.MediaCodec.native_dequeueOutputBuffer(Native Method)
```
-Since scrcpy v1.22, scrcpy automatically tries again with a lower definition
-before failing. This behavior can be disabled with `--no-downsize-on-error`.
-
-You could also try another [encoder](README.md#encoder).
-
-
-If you encounter this exception on Android 12, then just upgrade to scrcpy >=
-1.18 (see [#2129]):
-
-```
-> ERROR: Exception on thread Thread[main,5,main]
-java.lang.AssertionError: java.lang.reflect.InvocationTargetException
- at com.genymobile.scrcpy.wrappers.SurfaceControl.setDisplaySurface(SurfaceControl.java:75)
- ...
-Caused by: java.lang.reflect.InvocationTargetException
- at java.lang.reflect.Method.invoke(Native Method)
- at com.genymobile.scrcpy.wrappers.SurfaceControl.setDisplaySurface(SurfaceControl.java:73)
- ... 7 more
-Caused by: java.lang.IllegalArgumentException: displayToken must not be null
- at android.view.SurfaceControl$Transaction.setDisplaySurface(SurfaceControl.java:3067)
- at android.view.SurfaceControl.setDisplaySurface(SurfaceControl.java:2147)
- ... 9 more
-```
-
-[#2129]: https://github.com/Genymobile/scrcpy/issues/2129
-
-
-## Command line on Windows
-
-Since v1.22, a "shortcut" has been added to directly open a terminal in the
-scrcpy directory. Double-click on `open_a_terminal_here.bat`, then type your
-command. For example:
-
-```
-scrcpy --record file.mkv
-```
-
-You could also open a terminal and go to the scrcpy folder manually:
-
- 1. Press Windows+r, this opens a dialog box.
- 2. Type `cmd` and press Enter, this opens a terminal.
- 3. Go to your _scrcpy_ directory, by typing (adapt the path):
-
- ```bat
- cd C:\Users\user\Downloads\scrcpy-win64-xxx
- ```
-
- and press Enter
- 4. Type your command. For example:
-
- ```bat
- scrcpy --record file.mkv
- ```
-
-If you plan to always use the same arguments, create a file `myscrcpy.bat`
-(enable [show file extensions] to avoid confusion) in the `scrcpy` directory,
-containing your command. For example:
-
-```bat
-scrcpy --prefer-text --turn-screen-off --stay-awake
-```
-
-Then just double-click on that file.
-
-You could also edit (a copy of) `scrcpy-console.bat` or `scrcpy-noconsole.vbs`
-to add some arguments.
-
-[show file extensions]: https://www.howtogeek.com/205086/beginner-how-to-make-windows-show-file-extensions/
+then try with another [encoder](doc/video.md#codec).
## Translations
diff --git a/README.md b/README.md
index 765a6466..bc6f3bd3 100644
--- a/README.md
+++ b/README.md
@@ -4,11 +4,10 @@
_pronounced "**scr**een **c**o**py**"_
-[Read in another language](#translations)
-
-This application provides display and control of Android devices connected via
-USB or [over TCP/IP](#tcpip-wireless). It does not require any _root_ access.
-It works on _GNU/Linux_, _Windows_ and _macOS_.
+This application mirrors Android devices (video and audio) connected via
+USB or [over TCP/IP](doc/device.md#tcpip-wireless), and allows to control the
+device with the keyboard and the mouse of the computer. It does not require any
+_root_ access. It works on _Linux_, _Windows_ and _macOS_.
![screenshot](assets/screenshot-debian-600.jpg)
@@ -26,1161 +25,96 @@ It focuses on:
[lowlatency]: https://github.com/Genymobile/scrcpy/pull/646
Its features include:
- - [recording](#recording)
- - mirroring with [Android device screen off](#turn-screen-off)
- - [copy-paste](#copy-paste) in both directions
- - [configurable quality](#capture-configuration)
- - Android device [as a webcam (V4L2)](#v4l2loopback) (Linux-only)
- - [physical keyboard simulation (HID)](#physical-keyboard-simulation-hid)
- - [physical mouse simulation (HID)](#physical-mouse-simulation-hid)
- - [OTG mode](#otg)
+ - [audio forwarding](doc/audio.md) (Android >= 11)
+ - [recording](doc/recording.md)
+ - mirroring with [Android device screen off](doc/device.md#turn-screen-off)
+ - [copy-paste](doc/control.md#copy-paste) in both directions
+ - [configurable quality](doc/video.md)
+ - Android device [as a webcam (V4L2)](doc/v4l2.md) (Linux-only)
+ - [physical keyboard/mouse simulation (HID)](doc/hid-otg.md)
+ - [OTG mode](doc/hid-otg.md#otg)
- and more…
## Requirements
The Android device requires at least API 21 (Android 5.0).
-Make sure you [enable adb debugging][enable-adb] on your device(s).
+[Audio forwarding](doc/audio.md) is supported from API 30 (Android 11).
+
+Make sure you [enabled adb debugging][enable-adb] on your device(s).
[enable-adb]: https://developer.android.com/studio/command-line/adb.html#Enabling
-On some devices, you also need to enable [an additional option][control] to
-control it using a keyboard and mouse.
+On some devices, you also need to enable [an additional option][control] `USB
+debugging (Security Settings)` (this is an item different from `USB debugging`)
+to control it using a keyboard and mouse.
[control]: https://github.com/Genymobile/scrcpy/issues/70#issuecomment-373286323
## Get the app
-
+ - [Linux](doc/linux.md)
+ - [Windows](doc/windows.md)
+ - [macOS](doc/macos.md)
-### Summary
- - Linux: `apt install scrcpy`
- - Windows: [download][direct-win64]
- - macOS: `brew install scrcpy`
+## User documentation
-Build from sources: [BUILD] ([simplified process][BUILD_simple])
+The application provides a lot of features and configuration options. They are
+documented in the following pages:
-[BUILD]: BUILD.md
-[BUILD_simple]: BUILD.md#simple
+ - [Device](doc/device.md)
+ - [Video](doc/video.md)
+ - [Audio](doc/audio.md)
+ - [Control](doc/control.md)
+ - [Window](doc/window.md)
+ - [Recording](doc/recording.md)
+ - [Tunnels](doc/tunnels.md)
+ - [HID/OTG](doc/hid-otg.md)
+ - [Video4Linux](doc/v4l2.md)
+ - [Shortcuts](doc/shortcuts.md)
-### Linux
+## Resources
-On Debian and Ubuntu:
+ - [FAQ](FAQ.md)
+ - [Translations][wiki] (not necessarily up to date)
+ - [Build instructions](doc/build.md)
+ - [Developers](doc/develop.md)
-```
-apt install scrcpy
-```
+[wiki]: https://github.com/Genymobile/scrcpy/wiki
-On Arch Linux:
-```
-pacman -S scrcpy
-```
+## Articles
-A [Snap] package is available: [`scrcpy`][snap-link].
+- [Introducing scrcpy][article-intro]
+- [Scrcpy now works wirelessly][article-tcpip]
-[snap-link]: https://snapstats.org/snaps/scrcpy
+[article-intro]: https://blog.rom1v.com/2018/03/introducing-scrcpy/
+[article-tcpip]: https://www.genymotion.com/blog/open-source-project-scrcpy-now-works-wirelessly/
-[snap]: https://en.wikipedia.org/wiki/Snappy_(package_manager)
-For Fedora, a [COPR] package is available: [`scrcpy`][copr-link].
+## Contact
-[COPR]: https://fedoraproject.org/wiki/Category:Copr
-[copr-link]: https://copr.fedorainfracloud.org/coprs/zeno/scrcpy/
+If you encounter a bug, please read the [FAQ](FAQ.md) first, then open an [issue].
+[issue]: https://github.com/Genymobile/scrcpy/issues
-For Gentoo, an [Ebuild] is available: [`scrcpy/`][ebuild-link].
+For general questions or discussions, you can also use:
-[Ebuild]: https://wiki.gentoo.org/wiki/Ebuild
-[ebuild-link]: https://github.com/maggu2810/maggu2810-overlay/tree/master/app-mobilephone/scrcpy
+ - Reddit: [`r/scrcpy`](https://www.reddit.com/r/scrcpy)
+ - Twitter: [`@scrcpy_app`](https://twitter.com/scrcpy_app)
-You can also [build the app manually][BUILD] ([simplified
-process][BUILD_simple]).
+## Donate
-### Windows
+I'm [@rom1v](https://github.com/rom1v), the author and maintainer of _scrcpy_.
-For Windows, a prebuilt archive with all the dependencies (including `adb`) is
-available:
-
- - [`scrcpy-win64-v1.25.zip`][direct-win64]
- SHA-256: `db65125e9c65acd00359efb7cea9c05f63cc7ccd5833000cd243cc92f5053028`
-
-[direct-win64]: https://github.com/Genymobile/scrcpy/releases/download/v1.25/scrcpy-win64-v1.25.zip
-
-It is also available in [Chocolatey]:
-
-[Chocolatey]: https://chocolatey.org/
-
-```bash
-choco install scrcpy
-choco install adb # if you don't have it yet
-```
-
-And in [Scoop]:
-
-```bash
-scoop install scrcpy
-scoop install adb # if you don't have it yet
-```
-
-[Scoop]: https://scoop.sh
-
-You can also [build the app manually][BUILD].
-
-
-### macOS
-
-The application is available in [Homebrew]. Just install it:
-
-[Homebrew]: https://brew.sh/
-
-```bash
-brew install scrcpy
-```
-
-You need `adb`, accessible from your `PATH`. If you don't have it yet:
-
-```bash
-brew install android-platform-tools
-```
-
-It's also available in [MacPorts], which sets up `adb` for you:
-
-```bash
-sudo port install scrcpy
-```
-
-[MacPorts]: https://www.macports.org/
-
-
-You can also [build the app manually][BUILD].
-
-
-## Run
-
-Plug an Android device into your computer, and execute:
-
-```bash
-scrcpy
-```
-
-It accepts command-line arguments, listed by:
-
-```bash
-scrcpy --help
-```
-
-## Features
-
-### Capture configuration
-
-#### Reduce size
-
-Sometimes, it is useful to mirror an Android device at a lower resolution to
-increase performance.
-
-To limit both the width and height to some value (e.g. 1024):
-
-```bash
-scrcpy --max-size=1024
-scrcpy -m 1024 # short version
-```
-
-The other dimension is computed so that the Android device aspect ratio is
-preserved. That way, a device in 1920×1080 will be mirrored at 1024×576.
-
-
-#### Change bit-rate
-
-The default bit-rate is 8 Mbps. To change the video bitrate (e.g. to 2 Mbps):
-
-```bash
-scrcpy --video-bit-rate=2M
-scrcpy -b 2M # short version
-```
-
-#### Limit frame rate
-
-The capture frame rate can be limited:
-
-```bash
-scrcpy --max-fps=15
-```
-
-This is officially supported since Android 10, but may work on earlier versions.
-
-The actual capture framerate may be printed to the console:
-
-```
-scrcpy --print-fps
-```
-
-It may also be enabled or disabled at any time with MOD+i.
-
-
-#### Crop
-
-The device screen may be cropped to mirror only part of the screen.
-
-This is useful, for example, to mirror only one eye of the Oculus Go:
-
-```bash
-scrcpy --crop=1224:1440:0:0 # 1224x1440 at offset (0,0)
-```
-
-If `--max-size` is also specified, resizing is applied after cropping.
-
-
-#### Lock video orientation
-
-To lock the orientation of the mirroring:
-
-```bash
-scrcpy --lock-video-orientation # initial (current) orientation
-scrcpy --lock-video-orientation=0 # natural orientation
-scrcpy --lock-video-orientation=1 # 90° counterclockwise
-scrcpy --lock-video-orientation=2 # 180°
-scrcpy --lock-video-orientation=3 # 90° clockwise
-```
-
-This affects recording orientation.
-
-The [window may also be rotated](#rotation) independently.
-
-
-#### Codec
-
-The video codec can be selected. The possible values are `h264` (default),
-`h265` and `av1`:
-
-```bash
-scrcpy --video-codec=h264 # default
-scrcpy --video-codec=h265
-scrcpy --video-codec=av1
-```
-
-
-##### Encoder
-
-Some devices have more than one encoder for a specific codec, and some of them
-may cause issues or crash. It is possible to select a different encoder:
-
-```bash
-scrcpy --video-encoder=OMX.qcom.video.encoder.avc
-```
-
-To list the available encoders:
-
-```bash
-scrcpy --list-encoders
-```
-
-### Capture
-
-#### Recording
-
-It is possible to record the screen while mirroring:
-
-```bash
-scrcpy --record=file.mp4
-scrcpy -r file.mkv
-```
-
-To disable mirroring while recording:
-
-```bash
-scrcpy --no-display --record=file.mp4
-scrcpy -Nr file.mkv
-# interrupt recording with Ctrl+C
-```
-
-"Skipped frames" are recorded, even if they are not displayed in real time (for
-performance reasons). Frames are _timestamped_ on the device, so [packet delay
-variation] does not impact the recorded file.
-
-[packet delay variation]: https://en.wikipedia.org/wiki/Packet_delay_variation
-
-
-#### v4l2loopback
-
-On Linux, it is possible to send the video stream to a v4l2 loopback device, so
-that the Android device can be opened like a webcam by any v4l2-capable tool.
-
-The module `v4l2loopback` must be installed:
-
-```bash
-sudo apt install v4l2loopback-dkms
-```
-
-To create a v4l2 device:
-
-```bash
-sudo modprobe v4l2loopback
-```
-
-This will create a new video device in `/dev/videoN`, where `N` is an integer
-(more [options](https://github.com/umlaeute/v4l2loopback#options) are available
-to create several devices or devices with specific IDs).
-
-To list the enabled devices:
-
-```bash
-# requires v4l-utils package
-v4l2-ctl --list-devices
-
-# simple but might be sufficient
-ls /dev/video*
-```
-
-To start `scrcpy` using a v4l2 sink:
-
-```bash
-scrcpy --v4l2-sink=/dev/videoN
-scrcpy --v4l2-sink=/dev/videoN --no-display # disable mirroring window
-scrcpy --v4l2-sink=/dev/videoN -N # short version
-```
-
-(replace `N` with the device ID, check with `ls /dev/video*`)
-
-Once enabled, you can open your video stream with a v4l2-capable tool:
-
-```bash
-ffplay -i /dev/videoN
-vlc v4l2:///dev/videoN # VLC might add some buffering delay
-```
-
-For example, you could capture the video within [OBS].
-
-[OBS]: https://obsproject.com/
-
-
-#### Buffering
-
-It is possible to add buffering. This increases latency, but reduces jitter (see
-[#2464]).
-
-[#2464]: https://github.com/Genymobile/scrcpy/issues/2464
-
-The option is available for display buffering:
-
-```bash
-scrcpy --display-buffer=50 # add 50 ms buffering for display
-```
-
-and V4L2 sink:
-
-```bash
-scrcpy --v4l2-buffer=500 # add 500 ms buffering for v4l2 sink
-```
-
-
-### Connection
-
-#### TCP/IP (wireless)
-
-_Scrcpy_ uses `adb` to communicate with the device, and `adb` can [connect] to a
-device over TCP/IP. The device must be connected on the same network as the
-computer.
-
-##### Automatic
-
-An option `--tcpip` allows to configure the connection automatically. There are
-two variants.
-
-If the device (accessible at 192.168.1.1 in this example) already listens on a
-port (typically 5555) for incoming _adb_ connections, then run:
-
-```bash
-scrcpy --tcpip=192.168.1.1 # default port is 5555
-scrcpy --tcpip=192.168.1.1:5555
-```
-
-If _adb_ TCP/IP mode is disabled on the device (or if you don't know the IP
-address), connect the device over USB, then run:
-
-```bash
-scrcpy --tcpip # without arguments
-```
-
-It will automatically find the device IP address and adb port, enable TCP/IP
-mode if necessary, then connect to the device before starting.
-
-##### Manual
-
-Alternatively, it is possible to enable the TCP/IP connection manually using
-`adb`:
-
-1. Plug the device into a USB port on your computer.
-2. Connect the device to the same Wi-Fi network as your computer.
-3. Get your device IP address, in Settings → About phone → Status, or by
- executing this command:
-
- ```bash
- adb shell ip route | awk '{print $9}'
- ```
-
-4. Enable `adb` over TCP/IP on your device: `adb tcpip 5555`.
-5. Unplug your device.
-6. Connect to your device: `adb connect DEVICE_IP:5555` _(replace `DEVICE_IP`
-with the device IP address you found)_.
-7. Run `scrcpy` as usual.
-
-Since Android 11, a [Wireless debugging option][adb-wireless] allows to bypass
-having to physically connect your device directly to your computer.
-
-[adb-wireless]: https://developer.android.com/studio/command-line/adb#connect-to-a-device-over-wi-fi-android-11+
-
-If the connection randomly drops, run your `scrcpy` command to reconnect. If it
-says there are no devices/emulators found, try running `adb connect
-DEVICE_IP:5555` again, and then `scrcpy` as usual. If it still says there are
-none found, try running `adb disconnect`, and then run those two commands again.
-
-It may be useful to decrease the bit-rate and the resolution:
-
-```bash
-scrcpy --video-bit-rate=2M --max-size=800
-scrcpy -b2M -m800 # short version
-```
-
-[connect]: https://developer.android.com/studio/command-line/adb.html#wireless
-
-
-#### Multi-devices
-
-If several devices are listed in `adb devices`, you can specify the _serial_:
-
-```bash
-scrcpy --serial=0123456789abcdef
-scrcpy -s 0123456789abcdef # short version
-```
-
-The serial may also be provided via the environment variable `ANDROID_SERIAL`
-(also used by `adb`).
-
-If the device is connected over TCP/IP:
-
-```bash
-scrcpy --serial=192.168.0.1:5555
-scrcpy -s 192.168.0.1:5555 # short version
-```
-
-If only one device is connected via either USB or TCP/IP, it is possible to
-select it automatically:
-
-```bash
-# Select the only device connected via USB
-scrcpy -d # like adb -d
-scrcpy --select-usb # long version
-
-# Select the only device connected via TCP/IP
-scrcpy -e # like adb -e
-scrcpy --select-tcpip # long version
-```
-
-You can start several instances of _scrcpy_ for several devices.
-
-#### Autostart on device connection
-
-You could use [AutoAdb]:
-
-```bash
-autoadb scrcpy -s '{}'
-```
-
-[AutoAdb]: https://github.com/rom1v/autoadb
-
-#### Tunnels
-
-To connect to a remote device, it is possible to connect a local `adb` client to
-a remote `adb` server (provided they use the same version of the _adb_
-protocol).
-
-##### Remote ADB server
-
-To connect to a remote _adb server_, make the server listen on all interfaces:
-
-```bash
-adb kill-server
-adb -a nodaemon server start
-# keep this open
-```
-
-**Warning: all communications between clients and the _adb server_ are
-unencrypted.**
-
-Suppose that this server is accessible at 192.168.1.2. Then, from another
-terminal, run `scrcpy`:
-
-```bash
-# in bash
-export ADB_SERVER_SOCKET=tcp:192.168.1.2:5037
-scrcpy --tunnel-host=192.168.1.2
-```
-
-```cmd
-:: in cmd
-set ADB_SERVER_SOCKET=tcp:192.168.1.2:5037
-scrcpy --tunnel-host=192.168.1.2
-```
-
-```powershell
-# in PowerShell
-$env:ADB_SERVER_SOCKET = 'tcp:192.168.1.2:5037'
-scrcpy --tunnel-host=192.168.1.2
-```
-
-By default, `scrcpy` uses the local port used for `adb forward` tunnel
-establishment (typically `27183`, see `--port`). It is also possible to force a
-different tunnel port (it may be useful in more complex situations, when more
-redirections are involved):
-
-```
-scrcpy --tunnel-port=1234
-```
-
-
-##### SSH tunnel
-
-To communicate with a remote _adb server_ securely, it is preferable to use an
-SSH tunnel.
-
-First, make sure the _adb server_ is running on the remote computer:
-
-```bash
-adb start-server
-```
-
-Then, establish an SSH tunnel:
-
-```bash
-# local 5038 --> remote 5037
-# local 27183 <-- remote 27183
-ssh -CN -L5038:localhost:5037 -R27183:localhost:27183 your_remote_computer
-# keep this open
-```
-
-From another terminal, run `scrcpy`:
-
-```bash
-# in bash
-export ADB_SERVER_SOCKET=tcp:localhost:5038
-scrcpy
-```
-
-```cmd
-:: in cmd
-set ADB_SERVER_SOCKET=tcp:localhost:5038
-scrcpy
-```
-
-```powershell
-# in PowerShell
-$env:ADB_SERVER_SOCKET = 'tcp:localhost:5038'
-scrcpy
-```
-
-To avoid enabling remote port forwarding, you could force a forward connection
-instead (notice the `-L` instead of `-R`):
-
-```bash
-# local 5038 --> remote 5037
-# local 27183 --> remote 27183
-ssh -CN -L5038:localhost:5037 -L27183:localhost:27183 your_remote_computer
-# keep this open
-```
-
-From another terminal, run `scrcpy`:
-
-```bash
-# in bash
-export ADB_SERVER_SOCKET=tcp:localhost:5038
-scrcpy --force-adb-forward
-```
-
-```cmd
-:: in cmd
-set ADB_SERVER_SOCKET=tcp:localhost:5038
-scrcpy --force-adb-forward
-```
-
-```powershell
-# in PowerShell
-$env:ADB_SERVER_SOCKET = 'tcp:localhost:5038'
-scrcpy --force-adb-forward
-```
-
-
-Like for wireless connections, it may be useful to reduce quality:
-
-```
-scrcpy -b2M -m800 --max-fps=15
-```
-
-### Window configuration
-
-#### Title
-
-By default, the window title is the device model. It can be changed:
-
-```bash
-scrcpy --window-title='My device'
-```
-
-#### Position and size
-
-The initial window position and size may be specified:
-
-```bash
-scrcpy --window-x=100 --window-y=100 --window-width=800 --window-height=600
-```
-
-#### Borderless
-
-To disable window decorations:
-
-```bash
-scrcpy --window-borderless
-```
-
-#### Always on top
-
-To keep the _scrcpy_ window always on top:
-
-```bash
-scrcpy --always-on-top
-```
-
-#### Fullscreen
-
-The app may be started directly in fullscreen:
-
-```bash
-scrcpy --fullscreen
-scrcpy -f # short version
-```
-
-Fullscreen can then be toggled dynamically with MOD+f.
-
-#### Rotation
-
-The window may be rotated:
-
-```bash
-scrcpy --rotation=1
-```
-
-Possible values:
- - `0`: no rotation
- - `1`: 90 degrees counterclockwise
- - `2`: 180 degrees
- - `3`: 90 degrees clockwise
-
-The rotation can also be changed dynamically with MOD+←
-_(left)_ and MOD+→ _(right)_.
-
-Note that _scrcpy_ manages 3 different rotations:
- - MOD+r requests the device to switch between portrait
- and landscape (the current running app may refuse, if it does not support the
- requested orientation).
- - [`--lock-video-orientation`](#lock-video-orientation) changes the mirroring
- orientation (the orientation of the video sent from the device to the
- computer). This affects the recording.
- - `--rotation` (or MOD+←/MOD+→)
- rotates only the window content. This affects only the display, not the
- recording.
-
-
-### Other mirroring options
-
-#### Read-only
-
-To disable controls (everything which can interact with the device: input keys,
-mouse events, drag&drop files):
-
-```bash
-scrcpy --no-control
-scrcpy -n
-```
-
-#### Display
-
-If several displays are available, it is possible to select the display to
-mirror:
-
-```bash
-scrcpy --display=1
-```
-
-The list of display ids can be retrieved by:
-
-```bash
-scrcpy --list-displays
-```
-
-The secondary display may only be controlled if the device runs at least Android
-10 (otherwise it is mirrored as read-only).
-
-
-#### Stay awake
-
-To prevent the device from sleeping after a delay when the device is plugged in:
-
-```bash
-scrcpy --stay-awake
-scrcpy -w
-```
-
-The initial state is restored when _scrcpy_ is closed.
-
-
-#### Turn screen off
-
-It is possible to turn the device screen off while mirroring on start with a
-command-line option:
-
-```bash
-scrcpy --turn-screen-off
-scrcpy -S
-```
-
-Or by pressing MOD+o at any time.
-
-To turn it back on, press MOD+Shift+o.
-
-On Android, the `POWER` button always turns the screen on. For convenience, if
-`POWER` is sent via _scrcpy_ (via right-click or MOD+p),
-it will force to turn the screen off after a small delay (on a best effort
-basis). The physical `POWER` button will still cause the screen to be turned
-on.
-
-It can also be useful to prevent the device from sleeping:
-
-```bash
-scrcpy --turn-screen-off --stay-awake
-scrcpy -Sw
-```
-
-#### Power off on close
-
-To turn the device screen off when closing _scrcpy_:
-
-```bash
-scrcpy --power-off-on-close
-```
-
-#### Power on on start
-
-By default, on start, the device is powered on.
-
-To prevent this behavior:
-
-```bash
-scrcpy --no-power-on
-```
-
-
-#### Show touches
-
-For presentations, it may be useful to show physical touches (on the physical
-device).
-
-Android provides this feature in _Developers options_.
-
-_Scrcpy_ provides an option to enable this feature on start and restore the
-initial value on exit:
-
-```bash
-scrcpy --show-touches
-scrcpy -t
-```
-
-Note that it only shows _physical_ touches (by a finger on the device).
-
-
-#### Disable screensaver
-
-By default, _scrcpy_ does not prevent the screensaver from running on the
-computer.
-
-To disable it:
-
-```bash
-scrcpy --disable-screensaver
-```
-
-
-### Input control
-
-#### Rotate device screen
-
-Press MOD+r to switch between portrait and landscape
-modes.
-
-Note that it rotates only if the application in foreground supports the
-requested orientation.
-
-#### Copy-paste
-
-Any time the Android clipboard changes, it is automatically synchronized to the
-computer clipboard.
-
-Any Ctrl shortcut is forwarded to the device. In particular:
- - Ctrl+c typically copies
- - Ctrl+x typically cuts
- - Ctrl+v typically pastes (after computer-to-device
- clipboard synchronization)
-
-This typically works as you expect.
-
-The actual behavior depends on the active application though. For example,
-_Termux_ sends SIGINT on Ctrl+c instead, and _K-9 Mail_
-composes a new message.
-
-To copy, cut and paste in such cases (but only supported on Android >= 7):
- - MOD+c injects `COPY`
- - MOD+x injects `CUT`
- - MOD+v injects `PASTE` (after computer-to-device
- clipboard synchronization)
-
-In addition, MOD+Shift+v injects the computer
-clipboard text as a sequence of key events. This is useful when the component
-does not accept text pasting (for example in _Termux_), but it can break
-non-ASCII content.
-
-**WARNING:** Pasting the computer clipboard to the device (either via
-Ctrl+v or MOD+v) copies the content
-into the Android clipboard. As a consequence, any Android application could read
-its content. You should avoid pasting sensitive content (like passwords) that
-way.
-
-Some Android devices do not behave as expected when setting the device clipboard
-programmatically. An option `--legacy-paste` is provided to change the behavior
-of Ctrl+v and MOD+v so that they
-also inject the computer clipboard text as a sequence of key events (the same
-way as MOD+Shift+v).
-
-To disable automatic clipboard synchronization, use
-`--no-clipboard-autosync`.
-
-#### Pinch-to-zoom
-
-To simulate "pinch-to-zoom": Ctrl+_click-and-move_.
-
-More precisely, hold down Ctrl while pressing the left-click button.
-Until the left-click button is released, all mouse movements scale and rotate
-the content (if supported by the app) relative to the center of the screen.
-
-Technically, _scrcpy_ generates additional touch events from a "virtual finger"
-at a location inverted through the center of the screen.
-
-#### Physical keyboard simulation (HID)
-
-By default, _scrcpy_ uses Android key or text injection: it works everywhere,
-but is limited to ASCII.
-
-Alternatively, `scrcpy` can simulate a physical USB keyboard on Android to
-provide a better input experience (using [USB HID over AOAv2][hid-aoav2]): the
-virtual keyboard is disabled and it works for all characters and IME.
-
-[hid-aoav2]: https://source.android.com/devices/accessories/aoa2#hid-support
-
-However, it only works if the device is connected via USB.
-
-Note: On Windows, it may only work in [OTG mode](#otg), not while mirroring (it
-is not possible to open a USB device if it is already open by another process
-like the _adb daemon_).
-
-To enable this mode:
-
-```bash
-scrcpy --hid-keyboard
-scrcpy -K # short version
-```
-
-If it fails for some reason (for example because the device is not connected via
-USB), it automatically fallbacks to the default mode (with a log in the
-console). This allows using the same command line options when connected over
-USB and TCP/IP.
-
-In this mode, raw key events (scancodes) are sent to the device, independently
-of the host key mapping. Therefore, if your keyboard layout does not match, it
-must be configured on the Android device, in Settings → System → Languages and
-input → [Physical keyboard].
-
-This settings page can be started directly:
-
-```bash
-adb shell am start -a android.settings.HARD_KEYBOARD_SETTINGS
-```
-
-However, the option is only available when the HID keyboard is enabled (or when
-a physical keyboard is connected).
-
-[Physical keyboard]: https://github.com/Genymobile/scrcpy/pull/2632#issuecomment-923756915
-
-#### Physical mouse simulation (HID)
-
-Similarly to the physical keyboard simulation, it is possible to simulate a
-physical mouse. Likewise, it only works if the device is connected by USB.
-
-By default, _scrcpy_ uses Android mouse events injection with absolute
-coordinates. By simulating a physical mouse, a mouse pointer appears on the
-Android device, and relative mouse motion, clicks and scrolls are injected.
-
-To enable this mode:
-
-```bash
-scrcpy --hid-mouse
-scrcpy -M # short version
-```
-
-You can also add `--forward-all-clicks` to [forward all mouse
-buttons][forward_all_clicks].
-
-[forward_all_clicks]: #right-click-and-middle-click
-
-When this mode is enabled, the computer mouse is "captured" (the mouse pointer
-disappears from the computer and appears on the Android device instead).
-
-Special capture keys, either Alt or Super, toggle
-(disable or enable) the mouse capture. Use one of them to give the control of
-the mouse back to the computer.
-
-
-#### OTG
-
-It is possible to run _scrcpy_ with only physical keyboard and mouse simulation
-(HID), as if the computer keyboard and mouse were plugged directly to the device
-via an OTG cable.
-
-In this mode, `adb` (USB debugging) is not necessary, and mirroring is disabled.
-
-To enable OTG mode:
-
-```bash
-scrcpy --otg
-# Pass the serial if several USB devices are available
-scrcpy --otg -s 0123456789abcdef
-```
-
-It is possible to enable only HID keyboard or HID mouse:
-
-```bash
-scrcpy --otg --hid-keyboard # keyboard only
-scrcpy --otg --hid-mouse # mouse only
-scrcpy --otg --hid-keyboard --hid-mouse # keyboard and mouse
-# for convenience, enable both by default
-scrcpy --otg # keyboard and mouse
-```
-
-Like `--hid-keyboard` and `--hid-mouse`, it only works if the device is
-connected by USB.
-
-
-#### Text injection preference
-
-Two kinds of [events][textevents] are generated when typing text:
- - _key events_, signaling that a key is pressed or released;
- - _text events_, signaling that a text has been entered.
-
-By default, letters are injected using key events, so that the keyboard behaves
-as expected in games (typically for WASD keys).
-
-But this may [cause issues][prefertext]. If you encounter such a problem, you
-can avoid it by:
-
-```bash
-scrcpy --prefer-text
-```
-
-(but this will break keyboard behavior in games)
-
-On the contrary, you could force to always inject raw key events:
-
-```bash
-scrcpy --raw-key-events
-```
-
-These options have no effect on HID keyboard (all key events are sent as
-scancodes in this mode).
-
-[textevents]: https://blog.rom1v.com/2018/03/introducing-scrcpy/#handle-text-input
-[prefertext]: https://github.com/Genymobile/scrcpy/issues/650#issuecomment-512945343
-
-
-#### Key repeat
-
-By default, holding a key down generates repeated key events. This can cause
-performance problems in some games, where these events are useless anyway.
-
-To avoid forwarding repeated key events:
-
-```bash
-scrcpy --no-key-repeat
-```
-
-This option has no effect on HID keyboard (key repeat is handled by Android
-directly in this mode).
-
-
-#### Right-click and middle-click
-
-By default, right-click triggers BACK (or POWER on) and middle-click triggers
-HOME. To disable these shortcuts and forward the clicks to the device instead:
-
-```bash
-scrcpy --forward-all-clicks
-```
-
-
-### File drop
-
-#### Install APK
-
-To install an APK, drag & drop an APK file (ending with `.apk`) to the _scrcpy_
-window.
-
-There is no visual feedback, a log is printed to the console.
-
-
-#### Push file to device
-
-To push a file to `/sdcard/Download/` on the device, drag & drop a (non-APK)
-file to the _scrcpy_ window.
-
-There is no visual feedback, a log is printed to the console.
-
-The target directory can be changed on start:
-
-```bash
-scrcpy --push-target=/sdcard/Movies/
-```
-
-
-### Audio forwarding
-
-Audio is not forwarded by _scrcpy_. Use [sndcpy].
-
-Also see [issue #14].
-
-[sndcpy]: https://github.com/rom1v/sndcpy
-[issue #14]: https://github.com/Genymobile/scrcpy/issues/14
-
-
-## Shortcuts
-
-In the following list, MOD is the shortcut modifier. By default, it's
-(left) Alt or (left) Super.
-
-It can be changed using `--shortcut-mod`. Possible keys are `lctrl`, `rctrl`,
-`lalt`, `ralt`, `lsuper` and `rsuper`. For example:
-
-```bash
-# use RCtrl for shortcuts
-scrcpy --shortcut-mod=rctrl
-
-# use either LCtrl+LAlt or LSuper for shortcuts
-scrcpy --shortcut-mod=lctrl+lalt,lsuper
-```
-
-_[Super] is typically the Windows or Cmd key._
-
-[Super]: https://en.wikipedia.org/wiki/Super_key_(keyboard_button)
-
- | Action | Shortcut
- | ------------------------------------------- |:-----------------------------
- | Switch fullscreen mode | MOD+f
- | Rotate display left | MOD+← _(left)_
- | Rotate display right | MOD+→ _(right)_
- | Resize window to 1:1 (pixel-perfect) | MOD+g
- | Resize window to remove black borders | MOD+w \| _Double-left-click¹_
- | Click on `HOME` | MOD+h \| _Middle-click_
- | Click on `BACK` | MOD+b \| _Right-click²_
- | Click on `APP_SWITCH` | MOD+s \| _4th-click³_
- | Click on `MENU` (unlock screen)⁴ | MOD+m
- | Click on `VOLUME_UP` | MOD+↑ _(up)_
- | Click on `VOLUME_DOWN` | MOD+↓ _(down)_
- | Click on `POWER` | MOD+p
- | Power on | _Right-click²_
- | Turn device screen off (keep mirroring) | MOD+o
- | Turn device screen on | MOD+Shift+o
- | Rotate device screen | MOD+r
- | Expand notification panel | MOD+n \| _5th-click³_
- | Expand settings panel | MOD+n+n \| _Double-5th-click³_
- | Collapse panels | MOD+Shift+n
- | Copy to clipboard⁵ | MOD+c
- | Cut to clipboard⁵ | MOD+x
- | Synchronize clipboards and paste⁵ | MOD+v
- | Inject computer clipboard text | MOD+Shift+v
- | Enable/disable FPS counter (on stdout) | MOD+i
- | Pinch-to-zoom | Ctrl+_click-and-move_
- | Drag & drop APK file | Install APK from computer
- | Drag & drop non-APK file | [Push file to device](#push-file-to-device)
-
-_¹Double-click on black borders to remove them._
-_²Right-click turns the screen on if it was off, presses BACK otherwise._
-_³4th and 5th mouse buttons, if your mouse has them._
-_⁴For react-native apps in development, `MENU` triggers development menu._
-_⁵Only on Android >= 7._
-
-Shortcuts with repeated keys are executed by releasing and pressing the key a
-second time. For example, to execute "Expand settings panel":
-
- 1. Press and keep pressing MOD.
- 2. Then double-press n.
- 3. Finally, release MOD.
-
-All Ctrl+_key_ shortcuts are forwarded to the device, so they are
-handled by the active application.
-
-
-## Custom paths
-
-To use a specific `adb` binary, configure its path in the environment variable
-`ADB`:
-
-```bash
-ADB=/path/to/adb scrcpy
-```
-
-To override the path of the `scrcpy-server` file, configure its path in
-`SCRCPY_SERVER_PATH`.
-
-To override the icon, configure its path in `SCRCPY_ICON_PATH`.
-
-
-## Why the name _scrcpy_?
-
-A colleague challenged me to find a name as unpronounceable as [gnirehtet].
-
-[`strcpy`] copies a **str**ing; `scrcpy` copies a **scr**een.
-
-[gnirehtet]: https://github.com/Genymobile/gnirehtet
-[`strcpy`]: http://man7.org/linux/man-pages/man3/strcpy.3.html
-
-
-## How to build?
-
-See [BUILD].
-
-
-## Common issues
-
-See the [FAQ].
-
-[FAQ]: FAQ.md
-
-
-## Developers
-
-Read the [developers page].
-
-[developers page]: DEVELOP.md
+If you appreciate this application, you can [support my open source
+work][donate].
+[donate]: https://blog.rom1v.com/about/#support-my-open-source-work
## Licence
@@ -1198,30 +132,3 @@ Read the [developers page].
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
-## Articles
-
-- [Introducing scrcpy][article-intro]
-- [Scrcpy now works wirelessly][article-tcpip]
-
-[article-intro]: https://blog.rom1v.com/2018/03/introducing-scrcpy/
-[article-tcpip]: https://www.genymotion.com/blog/open-source-project-scrcpy-now-works-wirelessly/
-
-## Contact
-
-If you encounter a bug, please read the [FAQ] first, then open an [issue].
-
-[issue]: https://github.com/Genymobile/scrcpy/issues
-
-For general questions or discussions, you can also use:
-
- - Reddit: [`r/scrcpy`](https://www.reddit.com/r/scrcpy)
- - Twitter: [`@scrcpy_app`](https://twitter.com/scrcpy_app)
-
-## Translations
-
-Translations of this README in other languages are available in the [wiki].
-
-[wiki]: https://github.com/Genymobile/scrcpy/wiki
-
-Only this README file is guaranteed to be up-to-date.
diff --git a/doc/audio.md b/doc/audio.md
new file mode 100644
index 00000000..3755fe37
--- /dev/null
+++ b/doc/audio.md
@@ -0,0 +1,90 @@
+# Audio
+
+Audio forwarding is supported for devices with Android 11 or higher, and it is
+enabled by default:
+
+ - For **Android 12 or newer**, it works out-of-the-box.
+ - For **Android 11**, you'll need to ensure that the device screen is unlocked
+ when starting scrcpy. A fake popup will briefly appear to make the system
+ think that the shell app is in the foreground. Without this, audio capture
+ will fail.
+ - For **Android 10 or earlier**, audio cannot be captured and is automatically
+ disabled.
+
+If audio capture fails, then mirroring continues with video only (since audio is
+enabled by default, it is not acceptable to make scrcpy fail if it is not
+available), unless `--require-audio` is set.
+
+
+## No audio
+
+To disable audio:
+
+```
+scrcpy --no-audio
+```
+
+## Codec
+
+The audio codec can be selected. The possible values are `opus` (default), `aac`
+and `raw` (uncompressed PCM 16-bit LE):
+
+```bash
+scrcpy --audio-codec=opus # default
+scrcpy --audio-codec=aac
+scrcpy --audio-codec=raw
+```
+
+Several encoders may be available on the device. They can be listed by:
+
+```bash
+scrcpy --list-encoders
+```
+
+To select a specific encoder:
+
+```
+scrcpy --audio-codec=opus --audio-encoder='c2.android.opus.encoder'
+```
+
+For advanced usage, to pass arbitrary parameters to the [`MediaFormat`],
+check `--audio-codec-options` in the manpage or in `scrcpy --help`.
+
+[`MediaFormat`]: https://developer.android.com/reference/android/media/MediaFormat
+
+
+## Bit rate
+
+The default video bit-rate is 128Kbps. To change it:
+
+```bash
+scrcpy --audio-bit-rate=64K
+scrcpy --audio-bit-rate=64000 # equivalent
+```
+
+_This parameter does not apply to RAW audio codec (`--audio-codec=raw`)._
+
+
+## Buffering
+
+Audio buffering is unavoidable. It must be kept small enough so that the latency
+is acceptable, but large enough to minimize buffer underrun (causing audio
+glitches).
+
+The default buffer size is set to 50ms. It can be adjusted:
+
+```bash
+scrcpy --audio-buffer=40 # smaller than default
+scrcpy --audio-buffer=100 # higher than default
+```
+
+Note that this option changes the _target_ buffering. It is possible that this
+target buffering might not be reached (on frequent buffer underflow typically).
+
+If you don't interact with the device (to watch a video for example), a higher
+latency (for both [video](video.md#buffering) and audio) might be preferable to
+avoid glitches and smooth the playback:
+
+```
+scrcpy --display-buffer=200 --audio-buffer=200
+```
diff --git a/BUILD.md b/doc/build.md
similarity index 85%
rename from BUILD.md
rename to doc/build.md
index 51f8141e..31a04cfb 100644
--- a/BUILD.md
+++ b/doc/build.md
@@ -2,57 +2,16 @@
Here are the instructions to build _scrcpy_ (client and server).
-
-## Simple
-
-If you just want to install the latest release from `master`, follow this
-simplified process.
-
-First, you need to install the required packages:
-
-```bash
-# for Debian/Ubuntu
-sudo apt install ffmpeg libsdl2-2.0-0 adb wget \
- gcc git pkg-config meson ninja-build libsdl2-dev \
- libavcodec-dev libavdevice-dev libavformat-dev libavutil-dev \
- libswresample-dev libusb-1.0-0 libusb-1.0-0-dev
-```
-
-Then clone the repo and execute the installation script
-([source](install_release.sh)):
-
-```bash
-git clone https://github.com/Genymobile/scrcpy
-cd scrcpy
-./install_release.sh
-```
-
-When a new release is out, update the repo and reinstall:
-
-```bash
-git pull
-./install_release.sh
-```
-
-To uninstall:
-
-```bash
-sudo ninja -Cbuild-auto uninstall
-```
-
+If you just want to build and install the latest release, follow the simplified
+process described in [doc/linux.md](linux.md).
## Branches
-### `master`
-
-The `master` branch concerns the latest release, and is the home page of the
-project on GitHub.
-
-
-### `dev`
-
-`dev` is the current development branch. Every commit present in `dev` will be
-in the next release.
+There are two main branches:
+ - `master`: contains the latest release. It is the home page of the project on
+ GitHub.
+ - `dev`: the current development branch. Every commit present in `dev` will be
+ in the next release.
If you want to contribute code, please base your commits on the latest `dev`
branch.
@@ -69,6 +28,8 @@ the following files to a directory accessible from your `PATH`:
- `AdbWinApi.dll`
- `AdbWinUsbApi.dll`
+It is also available in scrcpy releases.
+
The client requires [FFmpeg] and [LibSDL2]. Just follow the instructions.
[adb]: https://developer.android.com/studio/command-line/adb.html
@@ -314,7 +275,8 @@ This installs several files:
- `/usr/local/share/zsh/site-functions/_scrcpy` (zsh completion)
- `/usr/local/share/bash-completion/completions/scrcpy` (bash completion)
-You can then [run](README.md#run) `scrcpy`.
+You can then run `scrcpy`.
+
### Uninstall
diff --git a/doc/control.md b/doc/control.md
new file mode 100644
index 00000000..0b060775
--- /dev/null
+++ b/doc/control.md
@@ -0,0 +1,149 @@
+# Control
+
+## Read-only
+
+To disable controls (everything which can interact with the device: input keys,
+mouse events, drag&drop files):
+
+```bash
+scrcpy --no-control
+scrcpy -n # short version
+```
+
+
+## Text injection preference
+
+Two kinds of [events][textevents] are generated when typing text:
+ - _key events_, signaling that a key is pressed or released;
+ - _text events_, signaling that a text has been entered.
+
+By default, letters are injected using key events, so that the keyboard behaves
+as expected in games (typically for WASD keys).
+
+But this may [cause issues][prefertext]. If you encounter such a problem, you
+can avoid it by:
+
+```bash
+scrcpy --prefer-text
+```
+
+(but this will break keyboard behavior in games)
+
+On the contrary, you could force to always inject raw key events:
+
+```bash
+scrcpy --raw-key-events
+```
+
+These options have no effect on HID keyboard (all key events are sent as
+scancodes in this mode).
+
+[textevents]: https://blog.rom1v.com/2018/03/introducing-scrcpy/#handle-text-input
+[prefertext]: https://github.com/Genymobile/scrcpy/issues/650#issuecomment-512945343
+
+
+## Copy-paste
+
+Any time the Android clipboard changes, it is automatically synchronized to the
+computer clipboard.
+
+Any Ctrl shortcut is forwarded to the device. In particular:
+ - Ctrl+c typically copies
+ - Ctrl+x typically cuts
+ - Ctrl+v typically pastes (after computer-to-device
+ clipboard synchronization)
+
+This typically works as you expect.
+
+The actual behavior depends on the active application though. For example,
+_Termux_ sends SIGINT on Ctrl+c instead, and _K-9 Mail_
+composes a new message.
+
+To copy, cut and paste in such cases (but only supported on Android >= 7):
+ - MOD+c injects `COPY`
+ - MOD+x injects `CUT`
+ - MOD+v injects `PASTE` (after computer-to-device
+ clipboard synchronization)
+
+In addition, MOD+Shift+v injects the computer
+clipboard text as a sequence of key events. This is useful when the component
+does not accept text pasting (for example in _Termux_), but it can break
+non-ASCII content.
+
+**WARNING:** Pasting the computer clipboard to the device (either via
+Ctrl+v or MOD+v) copies the content
+into the Android clipboard. As a consequence, any Android application could read
+its content. You should avoid pasting sensitive content (like passwords) that
+way.
+
+Some Android devices do not behave as expected when setting the device clipboard
+programmatically. An option `--legacy-paste` is provided to change the behavior
+of Ctrl+v and MOD+v so that they
+also inject the computer clipboard text as a sequence of key events (the same
+way as MOD+Shift+v).
+
+To disable automatic clipboard synchronization, use
+`--no-clipboard-autosync`.
+
+## Pinch-to-zoom
+
+To simulate "pinch-to-zoom": Ctrl+_click-and-move_.
+
+More precisely, hold down Ctrl while pressing the left-click button.
+Until the left-click button is released, all mouse movements scale and rotate
+the content (if supported by the app) relative to the center of the screen.
+
+Technically, _scrcpy_ generates additional touch events from a "virtual finger"
+at a location inverted through the center of the screen.
+
+
+## Key repeat
+
+By default, holding a key down generates repeated key events. This can cause
+performance problems in some games, where these events are useless anyway.
+
+To avoid forwarding repeated key events:
+
+```bash
+scrcpy --no-key-repeat
+```
+
+This option has no effect on HID keyboard (key repeat is handled by Android
+directly in this mode).
+
+
+## Right-click and middle-click
+
+By default, right-click triggers BACK (or POWER on) and middle-click triggers
+HOME. To disable these shortcuts and forward the clicks to the device instead:
+
+```bash
+scrcpy --forward-all-clicks
+```
+
+## File drop
+
+### Install APK
+
+To install an APK, drag & drop an APK file (ending with `.apk`) to the _scrcpy_
+window.
+
+There is no visual feedback, a log is printed to the console.
+
+
+### Push file to device
+
+To push a file to `/sdcard/Download/` on the device, drag & drop a (non-APK)
+file to the _scrcpy_ window.
+
+There is no visual feedback, a log is printed to the console.
+
+The target directory can be changed on start:
+
+```bash
+scrcpy --push-target=/sdcard/Movies/
+```
+
+## Physical keyboard and mouse simulation
+
+See the dedicated [HID/OTG](hid-otg.md) page.
diff --git a/DEVELOP.md b/doc/develop.md
similarity index 100%
rename from DEVELOP.md
rename to doc/develop.md
diff --git a/doc/device.md b/doc/device.md
new file mode 100644
index 00000000..c7e1ec04
--- /dev/null
+++ b/doc/device.md
@@ -0,0 +1,228 @@
+# Device
+
+## Selection
+
+If exactly one device is connected (i.e. listed by `adb devices`), then it is
+automatically selected.
+
+However, if there are multiple devices connected, you must specify the one to
+use in one of 4 ways:
+ - by its serial:
+ ```bash
+ scrcpy --serial=0123456789abcdef
+ scrcpy -s 0123456789abcdef # short version
+
+ # the serial is the ip:port if connected over TCP/IP (same behavior as adb)
+ scrcpy --serial=192.168.1.1:5555
+ ```
+ - the one connected over USB (if there is exactly one):
+ ```bash
+ scrcpy --select-usb
+ scrcpy -d # short version
+ ```
+ - the one connected over TCP/IP (if there is exactly one):
+ ```bash
+ scrcpy --select-tcpip
+ scrcpy -e # short version
+ ```
+ - a device already listening on TCP/IP (see [below](#tcpip-wireless)):
+ ```bash
+ scrcpy --tcpip=192.168.1.1:5555
+ scrcpy --tcpip=192.168.1.1 # default port is 5555
+ ```
+
+The serial may also be provided via the environment variable `ANDROID_SERIAL`
+(also used by `adb`):
+
+```bash
+# in bash
+export ANDROID_SERIAL=0123456789abcdef
+scrcpy
+```
+
+```cmd
+:: in cmd
+set ANDROID_SERIAL=0123456789abcdef
+scrcpy
+```
+
+```powershell
+# in PowerShell
+$env:ANDROID_SERIAL = '0123456789abcdef'
+scrcpy
+```
+
+
+## TCP/IP (wireless)
+
+_Scrcpy_ uses `adb` to communicate with the device, and `adb` can [connect] to a
+device over TCP/IP. The device must be connected on the same network as the
+computer.
+
+[connect]: https://developer.android.com/studio/command-line/adb.html#wireless
+
+
+### Automatic
+
+An option `--tcpip` allows to configure the connection automatically. There are
+two variants.
+
+If the device (accessible at 192.168.1.1 in this example) already listens on a
+port (typically 5555) for incoming _adb_ connections, then run:
+
+```bash
+scrcpy --tcpip=192.168.1.1 # default port is 5555
+scrcpy --tcpip=192.168.1.1:5555
+```
+
+If _adb_ TCP/IP mode is disabled on the device (or if you don't know the IP
+address), connect the device over USB, then run:
+
+```bash
+scrcpy --tcpip # without arguments
+```
+
+It will automatically find the device IP address and adb port, enable TCP/IP
+mode if necessary, then connect to the device before starting.
+
+
+### Manual
+
+Alternatively, it is possible to enable the TCP/IP connection manually using
+`adb`:
+
+1. Plug the device into a USB port on your computer.
+2. Connect the device to the same Wi-Fi network as your computer.
+3. Get your device IP address, in Settings → About phone → Status, or by
+ executing this command:
+
+ ```bash
+ adb shell ip route | awk '{print $9}'
+ ```
+
+4. Enable `adb` over TCP/IP on your device: `adb tcpip 5555`.
+5. Unplug your device.
+6. Connect to your device: `adb connect DEVICE_IP:5555` _(replace `DEVICE_IP`
+with the device IP address you found)_.
+7. Run `scrcpy` as usual.
+8. Run `adb disconnect` once you're done.
+
+Since Android 11, a [Wireless debugging option][adb-wireless] allows to bypass
+having to physically connect your device directly to your computer.
+
+[adb-wireless]: https://developer.android.com/studio/command-line/adb#connect-to-a-device-over-wi-fi-android-11+
+
+
+## Autostart
+
+A small tool (by the scrcpy author) allows to run arbitrary commands whenever a
+new Android device is connected: [AutoAdb]. It can be used to start scrcpy:
+
+```bash
+autoadb scrcpy -s '{}'
+```
+
+[AutoAdb]: https://github.com/rom1v/autoadb
+
+
+## Display
+
+If several displays are available on the Android device, it is possible to
+select the display to mirror:
+
+```bash
+scrcpy --display=1
+```
+
+The list of display ids can be retrieved by:
+
+```bash
+scrcpy --list-displays
+```
+
+A secondary display may only be controlled if the device runs at least Android
+10 (otherwise it is mirrored as read-only).
+
+
+## Actions
+
+Some command line arguments perform actions on the device itself while scrcpy is
+running.
+
+
+### Stay awake
+
+To prevent the device from sleeping after a delay **when the device is plugged
+in**:
+
+```bash
+scrcpy --stay-awake
+scrcpy -w
+```
+
+The initial state is restored when _scrcpy_ is closed.
+
+If the device is not plugged in (i.e. only connected over TCP/IP),
+`--stay-awake` has no effect (this is the Android behavior).
+
+
+### Turn screen off
+
+It is possible to turn the device screen off while mirroring on start with a
+command-line option:
+
+```bash
+scrcpy --turn-screen-off
+scrcpy -S # short version
+```
+
+Or by pressing MOD+o at any time (see
+[shortcuts](shortcuts.md)).
+
+To turn it back on, press MOD+Shift+o.
+
+On Android, the `POWER` button always turns the screen on. For convenience, if
+`POWER` is sent via _scrcpy_ (via right-click or MOD+p),
+it will force to turn the screen off after a small delay (on a best effort
+basis). The physical `POWER` button will still cause the screen to be turned on.
+
+It can also be useful to prevent the device from sleeping:
+
+```bash
+scrcpy --turn-screen-off --stay-awake
+scrcpy -Sw # short version
+```
+
+
+### Show touches
+
+For presentations, it may be useful to show physical touches (on the physical
+device). Android exposes this feature in _Developers options_.
+
+_Scrcpy_ provides an option to enable this feature on start and restore the
+initial value on exit:
+
+```bash
+scrcpy --show-touches
+scrcpy -t # short version
+```
+
+Note that it only shows _physical_ touches (by a finger on the device).
+
+
+### Power off on close
+
+To turn the device screen off when closing _scrcpy_:
+
+```bash
+scrcpy --power-off-on-close
+```
+
+### Power on on start
+
+By default, on start, the device is powered on. To prevent this behavior:
+
+```bash
+scrcpy --no-power-on
+```
+
diff --git a/doc/hid-otg.md b/doc/hid-otg.md
new file mode 100644
index 00000000..c64af752
--- /dev/null
+++ b/doc/hid-otg.md
@@ -0,0 +1,108 @@
+# HID/OTG
+
+By default, _scrcpy_ injects input events at the Android API level. As an
+alternative, when connected over USB, it is possible to send HID events, so that
+scrcpy behaves as if it was a physical keyboard and/or mouse connected to the
+Android device.
+
+A special [OTG](#otg) mode allows to control the device without mirroring (and
+without USB debugging).
+
+
+## Physical keyboard simulation
+
+By default, _scrcpy_ uses Android key or text injection. It works everywhere,
+but is limited to ASCII.
+
+Instead, it can simulate a physical USB keyboard on Android to provide a better
+input experience (using [USB HID over AOAv2][hid-aoav2]): the virtual keyboard
+is disabled and it works for all characters and IME.
+
+[hid-aoav2]: https://source.android.com/devices/accessories/aoa2#hid-support
+
+However, it only works if the device is connected via USB.
+
+Note: On Windows, it may only work in [OTG mode](#otg), not while mirroring (it
+is not possible to open a USB device if it is already open by another process
+like the _adb daemon_).
+
+To enable this mode:
+
+```bash
+scrcpy --hid-keyboard
+scrcpy -K # short version
+```
+
+If it fails for some reason (for example because the device is not connected via
+USB), it automatically fallbacks to the default mode (with a log in the
+console). This allows using the same command line options when connected over
+USB and TCP/IP.
+
+In this mode, raw key events (scancodes) are sent to the device, independently
+of the host key mapping. Therefore, if your keyboard layout does not match, it
+must be configured on the Android device, in Settings → System → Languages and
+input → [Physical keyboard].
+
+This settings page can be started directly:
+
+```bash
+adb shell am start -a android.settings.HARD_KEYBOARD_SETTINGS
+```
+
+However, the option is only available when the HID keyboard is enabled (or when
+a physical keyboard is connected).
+
+[Physical keyboard]: https://github.com/Genymobile/scrcpy/pull/2632#issuecomment-923756915
+
+
+## Physical mouse simulation
+
+By default, _scrcpy_ uses Android mouse events injection with absolute
+coordinates. By simulating a physical mouse, a mouse pointer appears on the
+Android device, and relative mouse motion, clicks and scrolls are injected.
+
+To enable this mode:
+
+```bash
+scrcpy --hid-mouse
+scrcpy -M # short version
+```
+
+When this mode is enabled, the computer mouse is "captured" (the mouse pointer
+disappears from the computer and appears on the Android device instead).
+
+Special capture keys, either Alt or Super, toggle
+(disable or enable) the mouse capture. Use one of them to give the control of
+the mouse back to the computer.
+
+
+## OTG
+
+It is possible to run _scrcpy_ with only physical keyboard and mouse simulation
+(HID), as if the computer keyboard and mouse were plugged directly to the device
+via an OTG cable.
+
+In this mode, `adb` (USB debugging) is not necessary, and mirroring is disabled.
+
+This is similar to `--hid-keyboard --hid-mouse`, but without mirroring.
+
+To enable OTG mode:
+
+```bash
+scrcpy --otg
+# Pass the serial if several USB devices are available
+scrcpy --otg -s 0123456789abcdef
+```
+
+It is possible to enable only HID keyboard or HID mouse:
+
+```bash
+scrcpy --otg --hid-keyboard # keyboard only
+scrcpy --otg --hid-mouse # mouse only
+scrcpy --otg --hid-keyboard --hid-mouse # keyboard and mouse
+# for convenience, enable both by default
+scrcpy --otg # keyboard and mouse
+```
+
+Like `--hid-keyboard` and `--hid-mouse`, it only works if the device is
+connected over USB.
diff --git a/doc/linux.md b/doc/linux.md
new file mode 100644
index 00000000..3b0c560d
--- /dev/null
+++ b/doc/linux.md
@@ -0,0 +1,79 @@
+# On Linux
+
+## Install
+
+
+
+Scrcpy is packaged in several distributions and package managers:
+
+ - Debian/Ubuntu: `apt install scrcpy`
+ - Arch Linux: `pacman -S scrcpy`
+ - Fedora: `dnf copr enable zeno/scrcpy && dnf install scrcpy`
+ - Gentoo: [ebuild][ebuild-link] file
+ - Snap: `snap install scrcpy`
+ - … (see [repology](https://repology.org/project/scrcpy/versions))
+
+[ebuild-link]: https://github.com/maggu2810/maggu2810-overlay/tree/master/app-mobilephone/scrcpy
+
+### Latest version
+
+However, the packaged version is not always the latest release. To install the
+latest release from `master`, follow this simplified process.
+
+First, you need to install the required packages:
+
+```bash
+# for Debian/Ubuntu
+sudo apt install ffmpeg libsdl2-2.0-0 adb wget \
+ gcc git pkg-config meson ninja-build libsdl2-dev \
+ libavcodec-dev libavdevice-dev libavformat-dev libavutil-dev \
+ libswresample-dev libusb-1.0-0 libusb-1.0-0-dev
+```
+
+Then clone the repo and execute the installation script
+([source](/install_release.sh)):
+
+```bash
+git clone https://github.com/Genymobile/scrcpy
+cd scrcpy
+./install_release.sh
+```
+
+When a new release is out, update the repo and reinstall:
+
+```bash
+git pull
+./install_release.sh
+```
+
+To uninstall:
+
+```bash
+sudo ninja -Cbuild-auto uninstall
+```
+
+_Note that this simplified process only works for released versions (it
+downloads a prebuilt server binary), so for example you can't use it for testing
+the development branch (`dev`)._
+
+_See [build.md](build.md) to build and install the app manually._
+
+
+## Run
+
+Once installed, run from a terminal:
+
+```bash
+scrcpy
+```
+
+or with arguments (here to disable audio and record to `file.mkv`):
+
+```bash
+scrcpy --no-audio --record=file.mkv
+```
+
+Documentation for command line arguments is available:
+ - `man scrcpy`
+ - `scrcpy --help`
+ - on [github](/README.md)
diff --git a/doc/macos.md b/doc/macos.md
new file mode 100644
index 00000000..3092dbdc
--- /dev/null
+++ b/doc/macos.md
@@ -0,0 +1,47 @@
+# On macOS
+
+## Install
+
+Scrcpy is available in [Homebrew]:
+
+```bash
+brew install scrcpy
+```
+
+[Homebrew]: https://brew.sh/
+
+You need `adb`, accessible from your `PATH`. If you don't have it yet:
+
+```bash
+brew install android-platform-tools
+```
+
+Alternatively, Scrcpy is also available in [MacPorts], which sets up `adb` for you:
+
+```bash
+sudo port install scrcpy
+```
+
+[MacPorts]: https://www.macports.org/
+
+_See [build.md](build.md) to build and install the app manually._
+
+
+## Run
+
+Once installed, run from a terminal:
+
+```bash
+scrcpy
+```
+
+or with arguments (here to disable audio and record to `file.mkv`):
+
+```bash
+scrcpy --no-audio --record=file.mkv
+```
+
+Documentation for command line arguments is available:
+ - `man scrcpy`
+ - `scrcpy --help`
+ - on [github](/README.md)
diff --git a/doc/recording.md b/doc/recording.md
new file mode 100644
index 00000000..4aad088c
--- /dev/null
+++ b/doc/recording.md
@@ -0,0 +1,44 @@
+# Recording
+
+To record video and audio streams while mirroring:
+
+```bash
+scrcpy --record=file.mp4
+scrcpy -r file.mkv
+```
+
+To record only the video:
+
+```bash
+scrcpy --no-audio --record=file.mp4
+```
+
+_It is currently not possible to record only the audio._
+
+To disable mirroring while recording:
+
+```bash
+scrcpy --no-display --record=file.mp4
+scrcpy -Nr file.mkv
+# interrupt recording with Ctrl+C
+```
+
+Timestamps are captured on the device, so [packet delay variation] does not
+impact the recorded file, which is always clean (only if you use `--record` of
+course, not if you capture your scrcpy window and audio output on the computer).
+
+[packet delay variation]: https://en.wikipedia.org/wiki/Packet_delay_variation
+
+The video and audio streams are encoded on the device, but are muxed on the
+client side. Two formats (containers) are supported:
+ - Matroska (`.mkv`)
+ - MP4 (`.mp4`)
+
+The container is automatically selected based on the filename.
+
+It is also possible to explicitly select a container (in that case the filename
+needs not end with `.mkv` or `.mp4`):
+
+```
+scrcpy --record=file --record-format=mkv
+```
diff --git a/doc/shortcuts.md b/doc/shortcuts.md
new file mode 100644
index 00000000..06cae428
--- /dev/null
+++ b/doc/shortcuts.md
@@ -0,0 +1,68 @@
+# Shortcuts
+
+Actions can be performed on the scrcpy window using keyboard and mouse
+shortcuts.
+
+In the following list, MOD is the shortcut modifier. By default, it's
+(left) Alt or (left) Super.
+
+It can be changed using `--shortcut-mod`. Possible keys are `lctrl`, `rctrl`,
+`lalt`, `ralt`, `lsuper` and `rsuper`. For example:
+
+```bash
+# use RCtrl for shortcuts
+scrcpy --shortcut-mod=rctrl
+
+# use either LCtrl+LAlt or LSuper for shortcuts
+scrcpy --shortcut-mod=lctrl+lalt,lsuper
+```
+
+_[Super] is typically the Windows or Cmd key._
+
+[Super]: https://en.wikipedia.org/wiki/Super_key_(keyboard_button)
+
+ | Action | Shortcut
+ | ------------------------------------------- |:-----------------------------
+ | Switch fullscreen mode | MOD+f
+ | Rotate display left | MOD+← _(left)_
+ | Rotate display right | MOD+→ _(right)_
+ | Resize window to 1:1 (pixel-perfect) | MOD+g
+ | Resize window to remove black borders | MOD+w \| _Double-left-click¹_
+ | Click on `HOME` | MOD+h \| _Middle-click_
+ | Click on `BACK` | MOD+b \| _Right-click²_
+ | Click on `APP_SWITCH` | MOD+s \| _4th-click³_
+ | Click on `MENU` (unlock screen)⁴ | MOD+m
+ | Click on `VOLUME_UP` | MOD+↑ _(up)_
+ | Click on `VOLUME_DOWN` | MOD+↓ _(down)_
+ | Click on `POWER` | MOD+p
+ | Power on | _Right-click²_
+ | Turn device screen off (keep mirroring) | MOD+o
+ | Turn device screen on | MOD+Shift+o
+ | Rotate device screen | MOD+r
+ | Expand notification panel | MOD+n \| _5th-click³_
+ | Expand settings panel | MOD+n+n \| _Double-5th-click³_
+ | Collapse panels | MOD+Shift+n
+ | Copy to clipboard⁵ | MOD+c
+ | Cut to clipboard⁵ | MOD+x
+ | Synchronize clipboards and paste⁵ | MOD+v
+ | Inject computer clipboard text | MOD+Shift+v
+ | Enable/disable FPS counter (on stdout) | MOD+i
+ | Pinch-to-zoom | Ctrl+_click-and-move_
+ | Drag & drop APK file | Install APK from computer
+ | Drag & drop non-APK file | [Push file to device](#push-file-to-device)
+
+_¹Double-click on black borders to remove them._
+_²Right-click turns the screen on if it was off, presses BACK otherwise._
+_³4th and 5th mouse buttons, if your mouse has them._
+_⁴For react-native apps in development, `MENU` triggers development menu._
+_⁵Only on Android >= 7._
+
+Shortcuts with repeated keys are executed by releasing and pressing the key a
+second time. For example, to execute "Expand settings panel":
+
+ 1. Press and keep pressing MOD.
+ 2. Then double-press n.
+ 3. Finally, release MOD.
+
+All Ctrl+_key_ shortcuts are forwarded to the device, so they are
+handled by the active application.
diff --git a/doc/tunnels.md b/doc/tunnels.md
new file mode 100644
index 00000000..987a0293
--- /dev/null
+++ b/doc/tunnels.md
@@ -0,0 +1,123 @@
+# Tunnels
+
+Scrcpy is designed to mirror local Android devices. Tunnels allow to connect to
+a remote device (e.g. over the Internet).
+
+To connect to a remote device, it is possible to connect a local `adb` client to
+a remote `adb` server (provided they use the same version of the _adb_
+protocol).
+
+
+## Remote ADB server
+
+To connect to a remote _adb server_, make the server listen on all interfaces:
+
+```bash
+adb kill-server
+adb -a nodaemon server start
+# keep this open
+```
+
+**Warning: all communications between clients and the _adb server_ are
+unencrypted.**
+
+Suppose that this server is accessible at 192.168.1.2. Then, from another
+terminal, run `scrcpy`:
+
+```bash
+# in bash
+export ADB_SERVER_SOCKET=tcp:192.168.1.2:5037
+scrcpy --tunnel-host=192.168.1.2
+```
+
+```cmd
+:: in cmd
+set ADB_SERVER_SOCKET=tcp:192.168.1.2:5037
+scrcpy --tunnel-host=192.168.1.2
+```
+
+```powershell
+# in PowerShell
+$env:ADB_SERVER_SOCKET = 'tcp:192.168.1.2:5037'
+scrcpy --tunnel-host=192.168.1.2
+```
+
+By default, `scrcpy` uses the local port used for `adb forward` tunnel
+establishment (typically `27183`, see `--port`). It is also possible to force a
+different tunnel port (it may be useful in more complex situations, when more
+redirections are involved):
+
+```
+scrcpy --tunnel-port=1234
+```
+
+
+## SSH tunnel
+
+To communicate with a remote _adb server_ securely, it is preferable to use an
+SSH tunnel.
+
+First, make sure the _adb server_ is running on the remote computer:
+
+```bash
+adb start-server
+```
+
+Then, establish an SSH tunnel:
+
+```bash
+# local 5038 --> remote 5037
+# local 27183 <-- remote 27183
+ssh -CN -L5038:localhost:5037 -R27183:localhost:27183 your_remote_computer
+# keep this open
+```
+
+From another terminal, run `scrcpy`:
+
+```bash
+# in bash
+export ADB_SERVER_SOCKET=tcp:localhost:5038
+scrcpy
+```
+
+```cmd
+:: in cmd
+set ADB_SERVER_SOCKET=tcp:localhost:5038
+scrcpy
+```
+
+```powershell
+# in PowerShell
+$env:ADB_SERVER_SOCKET = 'tcp:localhost:5038'
+scrcpy
+```
+
+To avoid enabling remote port forwarding, you could force a forward connection
+instead (notice the `-L` instead of `-R`):
+
+```bash
+# local 5038 --> remote 5037
+# local 27183 --> remote 27183
+ssh -CN -L5038:localhost:5037 -L27183:localhost:27183 your_remote_computer
+# keep this open
+```
+
+From another terminal, run `scrcpy`:
+
+```bash
+# in bash
+export ADB_SERVER_SOCKET=tcp:localhost:5038
+scrcpy --force-adb-forward
+```
+
+```cmd
+:: in cmd
+set ADB_SERVER_SOCKET=tcp:localhost:5038
+scrcpy --force-adb-forward
+```
+
+```powershell
+# in PowerShell
+$env:ADB_SERVER_SOCKET = 'tcp:localhost:5038'
+scrcpy --force-adb-forward
+```
diff --git a/doc/v4l2.md b/doc/v4l2.md
new file mode 100644
index 00000000..ea8c0eed
--- /dev/null
+++ b/doc/v4l2.md
@@ -0,0 +1,65 @@
+# Video4Linux
+
+On Linux, it is possible to send the video stream to a [v4l2] loopback device,
+so that the Android device can be opened like a webcam by any v4l2-capable tool.
+
+[v4l2]: https://en.wikipedia.org/wiki/Video4Linux
+
+The module `v4l2loopback` must be installed:
+
+```bash
+sudo apt install v4l2loopback-dkms
+```
+
+To create a v4l2 device:
+
+```bash
+sudo modprobe v4l2loopback
+```
+
+This will create a new video device in `/dev/videoN`, where `N` is an integer
+(more [options](https://github.com/umlaeute/v4l2loopback#options) are available
+to create several devices or devices with specific IDs).
+
+To list the enabled devices:
+
+```bash
+# requires v4l-utils package
+v4l2-ctl --list-devices
+
+# simple but might be sufficient
+ls /dev/video*
+```
+
+To start `scrcpy` using a v4l2 sink:
+
+```bash
+scrcpy --v4l2-sink=/dev/videoN
+scrcpy --v4l2-sink=/dev/videoN --no-display # disable mirroring window
+```
+
+(replace `N` with the device ID, check with `ls /dev/video*`)
+
+Once enabled, you can open your video stream with a v4l2-capable tool:
+
+```bash
+ffplay -i /dev/videoN
+vlc v4l2:///dev/videoN # VLC might add some buffering delay
+```
+
+For example, you could capture the video within [OBS] or within your video
+conference tool.
+
+[OBS]: https://obsproject.com/
+
+
+## Buffering
+
+By default, there is no video buffering, to get the lowest possible latency.
+
+As for the [video display](video.md#buffering), it is possible to add
+buffering to delay the v4l2 stream:
+
+```bash
+scrcpy --v4l2-buffer=300 # add 300ms buffering for v4l2 sink
+```
diff --git a/doc/video.md b/doc/video.md
new file mode 100644
index 00000000..a2e9d106
--- /dev/null
+++ b/doc/video.md
@@ -0,0 +1,175 @@
+# Video
+
+## Size
+
+By default, scrcpy attempts to mirror at the Android device resolution.
+
+It might be useful to mirror at a lower definition to increase performance. To
+limit both width and height to some maximum value (here 1024):
+
+```bash
+scrcpy --max-size=1024
+scrcpy -m 1024 # short version
+```
+
+The other dimension is computed so that the Android device aspect ratio is
+preserved. That way, a device in 1920×1080 will be mirrored at 1024×576.
+
+If encoding fails, scrcpy automatically tries again with a lower definition
+(unless `--no-downsize-on-error` is enabled).
+
+
+## Bit rate
+
+The default video bit-rate is 8 Mbps. To change it:
+
+```bash
+scrcpy --video-bit-rate=2M
+scrcpy --video-bit-rate=2000000 # equivalent
+scrcpy -b 2M # short version
+```
+
+
+## Frame rate
+
+The capture frame rate can be limited:
+
+```bash
+scrcpy --max-fps=15
+```
+
+The actual capture frame rate may be printed to the console:
+
+```
+scrcpy --print-fps
+```
+
+It may also be enabled or disabled at anytime with MOD+i
+(see [shortcuts](shortcuts.md)).
+
+The frame rate is intrinsically variable: a new frame is produced only when the
+screen content changes. For example, if you play a fullscreen video at 24fps on
+your device, you should not get more than 24 frames per second in scrcpy.
+
+
+## Codec
+
+The video codec can be selected. The possible values are `h264` (default),
+`h265` and `av1`:
+
+```bash
+scrcpy --video-codec=h264 # default
+scrcpy --video-codec=h265
+scrcpy --video-codec=av1
+```
+
+H265 may provide better quality, but H264 should provide lower latency.
+AV1 encoders are not common on current Android devices.
+
+Several encoders may be available on the device. They can be listed by:
+
+```bash
+scrcpy --list-encoders
+```
+
+Sometimes, the default encoder may have issues or even crash, so it is useful to
+try another one:
+
+```bash
+scrcpy --video-codec=h264 --video-encoder='OMX.qcom.video.encoder.avc'
+```
+
+For advanced usage, to pass arbitrary parameters to the [`MediaFormat`],
+check `--video-codec-options` in the manpage or in `scrcpy --help`.
+
+[`MediaFormat`]: https://developer.android.com/reference/android/media/MediaFormat
+
+
+## Rotation
+
+The rotation may be applied at 3 different levels:
+ - The [shortcut](shortcuts.md) MOD+r requests the
+ device to switch between portrait and landscape (the current running app may
+ refuse, if it does not support the requested orientation).
+ - `--lock-video-orientation` changes the mirroring orientation (the orientation
+ of the video sent from the device to the computer). This affects the
+ recording.
+ - `--rotation` rotates only the window content. This only affects the display,
+ not the recording. It may be changed dynamically at any time using the
+ [shortcuts](shortcuts.md) MOD+← and
+ MOD+→.
+
+To lock the mirroring orientation:
+
+```bash
+scrcpy --lock-video-orientation # initial (current) orientation
+scrcpy --lock-video-orientation=0 # natural orientation
+scrcpy --lock-video-orientation=1 # 90° counterclockwise
+scrcpy --lock-video-orientation=2 # 180°
+scrcpy --lock-video-orientation=3 # 90° clockwise
+```
+
+To set an initial window rotation:
+
+```bash
+scrcpy --rotation=0 # no rotation
+scrcpy --rotation=1 # 90 degrees counterclockwise
+scrcpy --rotation=2 # 180 degrees
+scrcpy --rotation=3 # 90 degrees clockwise
+```
+
+## Crop
+
+The device screen may be cropped to mirror only part of the screen.
+
+This is useful, for example, to mirror only one eye of the Oculus Go:
+
+```bash
+scrcpy --crop=1224:1440:0:0 # 1224x1440 at offset (0,0)
+```
+
+The values are expressed in the device natural orientation (portrait for a
+phone, landscape for a tablet).
+
+If `--max-size` is also specified, resizing is applied after cropping.
+
+
+## Buffering
+
+By default, there is no video buffering, to get the lowest possible latency.
+
+Buffering can be added to delay the video stream and compensate for jitter to
+get a smoother playback (see [#2464]).
+
+[#2464]: https://github.com/Genymobile/scrcpy/issues/2464
+
+The configuration is available independently for the display,
+[v4l2 sinks](video.md#video4linux) and [audio](audio.md#buffering) playback.
+
+```bash
+scrcpy --display-buffer=50 # add 50ms buffering for display
+scrcpy --v4l2-buffer=300 # add 300ms buffering for v4l2 sink
+scrcpy --audio-buffer=200 # set 200ms buffering for audio playback
+```
+
+They can be applied simultaneously:
+
+```bash
+scrcpy --display-buffer=50 --v4l2-buffer=300
+```
+
+
+## No display
+
+It is possible to capture an Android device without displaying a mirroring
+window. This option is available if either [recording](recording.md) or
+[v4l2](#video4linux) is enabled:
+
+```bash
+scrcpy --v4l2-sink=/dev/video2 --no-display
+scrcpy --record=file.mkv --no-display
+```
+
+## Video4Linux
+
+See the dedicated [Video4Linux](v4l2.md) page.
diff --git a/doc/window.md b/doc/window.md
new file mode 100644
index 00000000..b5b73921
--- /dev/null
+++ b/doc/window.md
@@ -0,0 +1,55 @@
+# Window
+
+## Title
+
+By default, the window title is the device model. It can be changed:
+
+```bash
+scrcpy --window-title='My device'
+```
+
+## Position and size
+
+The initial window position and size may be specified:
+
+```bash
+scrcpy --window-x=100 --window-y=100 --window-width=800 --window-height=600
+```
+
+## Borderless
+
+To disable window decorations:
+
+```bash
+scrcpy --window-borderless
+```
+
+## Always on top
+
+To keep the window always on top:
+
+```bash
+scrcpy --always-on-top
+```
+
+## Fullscreen
+
+The app may be started directly in fullscreen:
+
+```bash
+scrcpy --fullscreen
+scrcpy -f # short version
+```
+
+Fullscreen mode can then be toggled dynamically with MOD+f
+(see [shortcuts](shortcuts.md)).
+
+
+## Disable screensaver
+
+By default, _scrcpy_ does not prevent the screensaver from running on the
+computer. To disable it:
+
+```bash
+scrcpy --disable-screensaver
+```
diff --git a/doc/windows.md b/doc/windows.md
new file mode 100644
index 00000000..fd15a5a7
--- /dev/null
+++ b/doc/windows.md
@@ -0,0 +1,84 @@
+# On Windows
+
+## Install
+
+Download the [latest release]:
+
+ - [`scrcpy-win64-v1.25.zip`][direct-win64]
+ SHA-256: `db65125e9c65acd00359efb7cea9c05f63cc7ccd5833000cd243cc92f5053028`
+
+[release]: https://github.com/Genymobile/scrcpy/releases/latest
+[direct-win64]: https://github.com/Genymobile/scrcpy/releases/download/v1.25/scrcpy-win64-v1.25.zip
+
+and extract it.
+
+Alternatively, you could install it from packages manager, like [Chocolatey]:
+
+```bash
+choco install scrcpy
+choco install adb # if you don't have it yet
+```
+
+or [Scoop]:
+
+
+```bash
+scoop install scrcpy
+scoop install adb # if you don't have it yet
+```
+
+[Chocolatey]: https://chocolatey.org/
+[Scoop]: https://scoop.sh
+
+_See [build.md](build.md) to build and install the app manually._
+
+
+## Run
+
+Scrcpy is a command line application: it is mainly intended to be executed from
+a terminal with command line arguments.
+
+To open a terminal at the expected location, double-click on
+`open_a_terminal_here.bat` in your scrcpy directory, then type your command. For
+example, without arguments:
+
+```bash
+scrcpy
+```
+
+or with arguments (here to disable audio and record to `file.mkv`):
+
+```
+scrcpy --no-audio --record=file.mkv
+```
+
+Documentation for command line arguments is available:
+ - `scrcpy --help`
+ - on [github](/README.md)
+
+To start scrcpy directly without opening a terminal, double-click on one of
+these files:
+ - `scrcpy-console.bat`: start with a terminal open (it will close when scrcpy
+ terminates, unless an error occurs);
+ - `scrcpy-noconsole.vbs`: start without a terminal (but you won't see any error
+ message).
+
+_Avoid double-clicking on `scrcpy.exe` directly: on error, the terminal would
+close immediately and you won't have time to read any error message (this
+executable is intended to be run from the terminal). Use `scrcpy-console.bat`
+instead._
+
+If you plan to always use the same arguments, create a file `myscrcpy.bat`
+(enable [show file extensions] to avoid confusion) containing your command, For
+example:
+
+```bash
+scrcpy --prefer-text --turn-screen-off --stay-awake
+```
+
+[show file extensions]: https://www.howtogeek.com/205086/beginner-how-to-make-windows-show-file-extensions/
+
+Then just double-click on that file.
+
+You could also edit (a copy of) `scrcpy-console.bat` or `scrcpy-noconsole.vbs`
+to add some arguments.