Skip to main content

Overview

The VideoDecoder class provides hardware-accelerated H.264/AVC video decoding using Android’s MediaCodec API. It runs in a separate thread and renders decoded frames directly to a Surface. Package: org.client.scrcpy.decoder Video Codec: video/avc (H.264/AVC)

Initialization

start()

Starts the decoder worker thread.
Example:

stop()

Stops the decoder and releases resources.
Example:

Configuration

configure()

Configures the MediaCodec decoder with stream parameters.
Surface
required
Target surface for rendering decoded frames
int
required
Video width in pixels
int
required
Video height in pixels
ByteBuffer
required
Codec-specific data 0 (SPS - Sequence Parameter Set)
ByteBuffer
required
Codec-specific data 1 (PPS - Picture Parameter Set)
Example:
Internal Implementation:
Calling configure() while already configured will stop the current decoder and create a new one. This allows dynamic reconfiguration for resolution changes.

Decoding

decodeSample()

Queues an encoded video sample for decoding.
byte[]
required
Byte array containing the encoded video frame
int
required
Starting position in the data array
int
required
Number of bytes to decode
long
required
Presentation timestamp in microseconds
int
required
MediaCodec flags (e.g., MediaCodec.BUFFER_FLAG_KEY_FRAME)
Example:
Frame Processing:

VideoPacket Structure

Video data is transmitted using the VideoPacket structure.

Packet Format

Header (10 bytes):
Total packet structure:

Flag Types

byte
Value: 0 - Regular P-frame or B-frame
byte
Value: 1 - I-frame (keyframe)
byte
Value: 2 - Configuration data (SPS/PPS)
byte
Value: 4 - End of stream

StreamSettings

Extracted from CONFIG packets containing SPS/PPS data.
Example:

Usage Example

Complete example of setting up and using the video decoder:

Threading Model

The VideoDecoder uses an internal Worker thread:

Performance Considerations

The decoder uses hardware acceleration. Ensure that:
  • The device supports H.264/AVC hardware decoding
  • The Surface is properly initialized before calling configure()
  • Frame rates don’t exceed device capabilities
Key Points:
  • Decoded frames render directly to the Surface (zero-copy)
  • Input buffer dequeue timeout is set to -1 (wait indefinitely)
  • Output buffer dequeue timeout is 0 (non-blocking)
  • Setting releaseOutputBuffer(index, true) renders the frame

See Also