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:

  • int
  • long
  • float
  • string (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-codec and --audio-codec to choose between H.264/H.265/AV1 and Opus/AAC/FLAC/RAW respectively.
  • Implementation Choice: Use --video-encoder and --audio-encoder to select specific hardware or software encoder implementations by name.
  • Codec Parameters: The --video-codec-options and --audio-codec-options flags pass typed key-value pairs directly to Android's MediaFormat, parsed by CodecOption.java and applied in SurfaceEncoder.java and AudioEncoder.java.
  • Decoder Control: Scrcpy uses FFmpeg defaults with no exposed codec settings; only buffering delays (--video-buffer, --audio-buffer, --v4l2-buffer) are configurable in scrcpy.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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →