Scrcpy Encoder and Decoder Options: Complete Configuration Guide
Scrcpy exposes extensive encoder controls including codec selection, specific encoder implementations, and codec-specific parameters through --video-codec-options and --audio-codec-options, while keeping decoder configuration minimal with only buffering delays adjustable on the client side.
The Genymobile/scrcpy project provides deep control over media encoding through its Android server component, which interfaces directly with the Android MediaCodec API. While encoder and decoder options are extensive on the server side, the client-side decoder intentionally uses FFmpeg libavcodec defaults with limited configurability.
Video Encoder Options
Scrcpy provides granular control over video encoding through three distinct mechanisms: codec selection, encoder implementation choice, and codec-specific parameter injection.
Selecting Video Codecs (--video-codec)
The --video-codec flag controls which video standard the Android server uses for encoding. In server/src/main/java/com/genymobile/scrcpy/video/VideoCodec.java, scrcpy defines three supported codecs:
- H264 (default)
- H265 (HEVC)
- AV1
The selection is stored in Options.videoCodec as defined in Options.java lines 30-33.
Choosing Specific Encoder Implementations (--video-encoder)
Android devices often contain multiple encoder implementations for the same codec (hardware-accelerated vs. software). The --video-encoder flag accepts the specific encoder name as reported by MediaCodecList.
In Options.java lines 408-412, this value is stored as Options.videoEncoder, where an empty string indicates the system default.
Configuring Codec-Specific Parameters (--video-codec-options)
The most powerful encoder control is --video-codec-options, which accepts a comma-separated list of key[:type]=value pairs that map directly to Android MediaFormat fields.
The parsing logic resides in server/src/main/java/com/genymobile/scrcpy/util/CodecOption.java, which supports four types:
intlongfloatstring(default when type is omitted)
These options are applied in SurfaceEncoder.java lines 256-281 when constructing the MediaFormat for the video encoder.
Audio Encoder Options
Audio encoding follows the same three-tier pattern as video, with codec selection, encoder selection, and codec options.
Audio Codec Selection (--audio-codec)
In server/src/main/java/com/genymobile/scrcpy/audio/AudioCodec.java, scrcpy defines four supported audio codecs:
- OPUS (default)
- AAC
- FLAC
- RAW (uncompressed PCM)
The selection is stored in Options.audioCodec as defined in Options.java line 31.
Audio Encoder Implementation (--audio-encoder)
Similar to video, --audio-encoder allows selection of specific encoder implementations (e.g., c2.android.opus.encoder vs. hardware alternatives). This is stored in Options.audioEncoder per Options.java lines 413-416.
Audio Codec Parameters (--audio-codec-options)
The --audio-codec-options flag accepts the same key[:type]=value syntax as video options. These are parsed by CodecOption.java and applied in AudioEncoder.java lines 78-94 when configuring the MediaFormat for audio encoding.
Decoder and Buffering Options
Scrcpy intentionally limits decoder configuration. The client uses FFmpeg libavcodec with default settings, exposing only buffering controls that affect presentation timing rather than decoding parameters.
Client-Side Buffering Controls
The decoder output pipeline supports two buffering options defined in app/src/scrcpy.c lines 78-85:
--video-buffer=ms: Adds a delay after video frame decoding before presentation--audio-buffer=ms: Adds a delay after audio packet decoding before playback
These values are stored in the sc_delay_buffer structure and help compensate for network jitter without modifying the decoder itself.
V4L2 Sink Buffering
When using --v4l2-sink to output to a Video4Linux2 device, the --v4l2-buffer=ms option controls buffering specifically for that output path, also defined in scrcpy.c.
How Codec Options Map to Android MediaFormat
The --video-codec-options and --audio-codec-options flags provide direct access to Android's MediaFormat configuration. When the scrcpy server receives these options, CodecOption.java parses the comma-separated list into typed key-value pairs.
For example, the option profile:int=2 becomes a call to MediaFormat.setInteger("profile", 2) inside SurfaceEncoder.java or AudioEncoder.java. Supported keys depend on the specific codec but typically include:
bitrate(int)profile(int)level(int)color-format(int)complexity(int)flac-compression-level(int) for FLAC audio
Summary
- Encoder Selection: Scrcpy exposes
--video-codecand--audio-codecto choose between H.264/H.265/AV1 and Opus/AAC/FLAC/RAW respectively. - Implementation Choice: Use
--video-encoderand--audio-encoderto select specific hardware or software encoder implementations by name. - Codec Parameters: The
--video-codec-optionsand--audio-codec-optionsflags pass typed key-value pairs directly to Android'sMediaFormat, parsed byCodecOption.javaand applied inSurfaceEncoder.javaandAudioEncoder.java. - Decoder Control: Scrcpy uses FFmpeg defaults with no exposed codec settings; only buffering delays (
--video-buffer,--audio-buffer,--v4l2-buffer) are configurable inscrcpy.c.
Frequently Asked Questions
How do I list available encoders on my device?
Scrcpy does not provide a built-in command to list encoders, but you can use Android's adb shell cmd media.codec or third-party apps to enumerate available MediaCodec implementations. Once identified, pass the exact encoder name to --video-encoder or --audio-encoder.
What codec options are available for H.265 encoding?
H.265 (HEVC) encoder options depend on your device's MediaCodec implementation. Common options include profile (int), level (int), tier (int), and bitrate (int). Pass these via --video-codec-options=profile:int=1,level:int=93 according to the Android MediaFormat HEVC specification.
Can I adjust decoder settings like threads or hardware acceleration?
No. Scrcpy's client-side decoder uses FFmpeg libavcodec with default settings and does not expose thread count, hardware acceleration flags, or low-level decoder parameters. The only decoder-related controls are the buffering options (--video-buffer, --audio-buffer) that affect presentation timing.
How do I troubleshoot encoder errors when using custom codec options?
If the encoder fails to configure, scrcpy will output an error from the Android MediaCodec layer. Verify that your option keys match the MediaFormat fields supported by your specific encoder (use adb logcat to see detailed MediaCodec errors). Ensure types match (int, long, float, string) as parsed by CodecOption.java.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →