> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/zwc456baby/ScrcpyForAndroid/llms.txt
> Use this file to discover all available pages before exploring further.

# Architecture Overview

> Deep dive into Scrcpy for Android's client-server architecture and internal components

## Architecture Overview

Scrcpy for Android uses a client-server architecture to enable Android-to-Android screen mirroring and control. The application is split into two distinct modules that communicate over TCP sockets.

## Two-Module Structure

The project consists of two independent modules:

<CardGroup cols={2}>
  <Card title="Client (App Module)" icon="mobile">
    Located in `app/src/main/java/org/client/scrcpy/`

    Runs on the controlling Android device and handles:

    * Video/audio decoding
    * Display rendering
    * Touch input capture
    * Network communication
  </Card>

  <Card title="Server Module" icon="server">
    Located in `server/src/main/java/org/server/scrcpy/`

    Runs on the target Android device and handles:

    * Screen capture
    * Video/audio encoding
    * Input event injection
    * ADB socket management
  </Card>
</CardGroup>

## Client-Server Communication

The architecture follows a bidirectional communication pattern:

```mermaid theme={null}
sequenceDiagram
    participant Client as Client Device<br/>(App Module)
    participant ADB as ADB Server
    participant Server as Target Device<br/>(Server Module)
    
    Client->>ADB: Connect to target:5555
    Client->>ADB: Push scrcpy-server.jar
    Client->>ADB: Forward tcp:7008 to tcp:7007
    ADB->>Server: Execute server JAR
    Server->>Server: Listen on port 7007
    Server->>Client: Accept connection
    Server->>Client: Send device resolution (16 bytes)
    
    par Video/Audio Streaming
        Server->>Client: Video packets (H.264)
        Server->>Client: Audio packets (AAC)
    and Input Events
        Client->>Server: Touch events (20 bytes)
        Client->>Server: Key events (4 bytes)
    end
```

## Video Streaming Pipeline

The video streaming process involves multiple stages from capture to display:

### Server Side (Encoding)

1. **Screen Capture** (`ScreenCapture.java`)
   * Uses Android's `MediaCodec` API with `VirtualDisplay`
   * Captures screen content as a `Surface`
   * Supports rotation changes dynamically

2. **Video Encoding** (`ScreenEncoder.java`)
   * Encodes to H.264 (AVC) format
   * Configuration: `bitRate`, `frameRate` (default 60fps), `iFrameInterval` (default 10s)
   * Packets are tagged with flags: `CONFIG`, `KEY_FRAME`, `FRAME`, or `END`
   * Each packet includes a presentation timestamp

3. **Packet Structure** (`VideoPacket.java`)
   ```text theme={null}
   [Type (1 byte)][Flag (1 byte)][PTS (8 bytes)][Size (4 bytes)][Data (N bytes)]
   ```

### Client Side (Decoding)

1. **Network Reception** (`Scrcpy.java:342-470`)
   * Reads packets from `DataInputStream`
   * Packet size is transmitted first (4 bytes)
   * Validates packet size (max 4MB per packet)

2. **Video Decoding** (`VideoDecoder.java`)
   * Configures `MediaCodec` with SPS/PPS from CONFIG packets
   * Decodes H.264 stream to `Surface`
   * Handles surface updates on rotation

3. **Rendering**
   * Direct rendering to `SurfaceView` via `MediaCodec`
   * Aspect ratio preservation with padding calculation

## Audio Streaming Pipeline

Audio follows a parallel pipeline to video:

### Server Side

* **Audio Capture** (`AudioCapture.java`, `AudioDirectCapture.java`)
  * Captures system audio using `AudioRecord`
  * Default bitrate: 128kbps
  * Runs asynchronously in separate thread (`ScreenEncoder.java:113-129`)

* **Audio Encoding** (`AudioEncoder.java`)
  * Encodes to AAC format
  * Packets tagged with `CONFIG`, `FRAME`, or `END` flags

### Client Side

* **Audio Decoding** (`AudioDecoder.java`)
  * Decodes AAC packets
  * Configures from CONFIG packet data
  * Synchronized with video using presentation timestamps

## Touch Event Handling Flow

Touch events flow from the client device to inject input on the target:

```mermaid theme={null}
graph LR
    A[User Touch] --> B[SurfaceView.onTouch]
    B --> C[Scrcpy.touchevent]
    C --> D[Coordinate Scaling]
    D --> E[Multi-touch Handling]
    E --> F[Event Queue]
    F --> G[Serialize to Bytes]
    G --> H[DataOutputStream]
    H --> I[Network]
    I --> J[Server InputStream]
    J --> K[EventController.control]
    K --> L[PointersState]
    L --> M[MotionEvent.obtain]
    M --> N[InputManager.injectEvent]
```

### Touch Event Protocol

Each touch event is serialized as 20 bytes:

```java theme={null}
[action (4)][buttonState (4)][x (4)][y (4)][pointerId (4)]
```

### Coordinate Transformation

The client performs coordinate scaling (`Scrcpy.java:136-182`):

1. Calculate remote device aspect ratio
2. Scale local coordinates to remote resolution
3. Handle landscape/portrait orientation
4. Support multi-touch (up to `MAX_POINTERS`)

### Server-Side Injection

The server receives events and injects them (`EventController.java:66-121`):

1. Read 20-byte buffer from input stream
2. Deserialize action, coordinates, and pointer ID
3. Convert to physical screen coordinates
4. Create `MotionEvent` with proper tool type (`TOOL_TYPE_FINGER`)
5. Handle multi-pointer actions (`ACTION_POINTER_DOWN/UP`)
6. Inject via `InputManager.injectInputEvent()`

## ADB Port Forwarding Mechanism

The connection setup relies on ADB's port forwarding feature:

### Connection Establishment

1. **ADB Connection** (`SendCommands.java:92-114`)
   ```java theme={null}
   adb connect <ip>:<port>  // Default port 5555
   adb push scrcpy-server.jar /data/local/tmp/
   adb forward tcp:7008 tcp:7007
   ```

2. **Server Socket** (`DroidConnection.java:27-36`)
   * Server opens `ServerSocket` on port **7007**
   * Waits for incoming connection
   * Validates client IP address

3. **Client Socket** (`Scrcpy.java:227-290`)
   * Client connects to `127.0.0.1:7008` (forwarded port)
   * Connection timeout: 5000ms
   * Retry mechanism: up to 50 attempts

### Initial Handshake

1. Server sends device resolution as first packet (16 bytes):
   ```java theme={null}
   [width (4 bytes)][height (4 bytes)][0 (4 bytes)][0 (4 bytes)]
   ```

2. Client reads resolution and configures decoders

3. Bidirectional streaming begins

## Key Components Reference

| Component              | Location                                     | Responsibility                                  |
| ---------------------- | -------------------------------------------- | ----------------------------------------------- |
| `Server.java`          | server/src/main/java/org/server/scrcpy/      | Entry point, orchestrates server components     |
| `Scrcpy.java`          | app/src/main/java/org/client/scrcpy/         | Client service, manages connection and decoding |
| `DroidConnection.java` | server/src/main/java/org/server/scrcpy/      | Socket management on server                     |
| `ScreenEncoder.java`   | server/src/main/java/org/server/scrcpy/      | Video encoding and streaming                    |
| `AudioEncoder.java`    | server/src/main/java/org/server/scrcpy/      | Audio encoding and streaming                    |
| `EventController.java` | server/src/main/java/org/server/scrcpy/      | Input event handling and injection              |
| `VideoDecoder.java`    | app/src/main/java/org/client/scrcpy/decoder/ | Video decoding on client                        |
| `AudioDecoder.java`    | app/src/main/java/org/client/scrcpy/decoder/ | Audio decoding on client                        |

## Performance Considerations

<AccordionGroup>
  <Accordion title="Video Encoding">
    * Default: 60fps, adjustable via `Options.java`
    * Resolution must be multiple of 8 (H.264 requirement)
    * Key frame interval: 10 seconds
    * Bitrate configurable per connection
  </Accordion>

  <Accordion title="Network Buffering">
    * Client polls input stream with `available()` check
    * Events queued in `LinkedList` for async sending
    * Frame dropping based on presentation timestamp delay
  </Accordion>

  <Accordion title="Threading Model">
    * Server: Main thread for video encoding, separate thread for event controller
    * Client: Decoder threads managed by `MediaCodec`, main loop in service thread
  </Accordion>
</AccordionGroup>

<Note>
  The architecture is designed for low-latency local network operation. For public network use, additional latency management may be required.
</Note>
