System Architecture
Monibuca V6 is a high-performance streaming media server engine written in Rust. This article introduces its overall architecture design.
Interactive Architecture Diagram
Section titled “Interactive Architecture Diagram”Overall Architecture
Section titled “Overall Architecture”┌─────────────────────────────────────────────────────────────────┐│ Monibuca Engine ││ ││ ┌──────────┐ ┌─────────────────┐ ┌───────────────────┐ ││ │ Protocol │ │ StreamManager │ │ PluginManager │ ││ │ Plugins │───▶│ │◀───│ │ ││ │ (RTMP, │ │ ┌───────────┐ │ │ init / start / │ ││ │ RTSP, │ │ │ Registry │ │ │ stop / reload │ ││ │ HLS, │ │ └───────────┘ │ └───────────────────┘ ││ │ WebRTC, │ │ ┌───────────┐ │ ┌───────────────────┐ ││ │ SRT...) │ │ │ Lifecycle │ │ │ EngineContext │ ││ └──────────┘ │ └───────────┘ │ │ (IoC Container) │ ││ │ ┌───────────┐ │ └───────────────────┘ ││ │ │ WaitQueue │ │ ││ │ └───────────┘ │ ┌───────────────────┐ ││ └────────┬────────┘ │ ConfigManager │ ││ │ │ (YAML + API) │ ││ ▼ └───────────────────┘ ││ ┌─────────────────────────────────────┐ ││ │ Stream Instance │ ││ │ │ ││ │ Publisher ──▶ RingBuffer ──▶ Dispatcher ──▶ Subs ││ │ │ │ │ ││ │ VideoTrack AudioTrack DispatcherPool ││ └─────────────────────────────────────┘ │└─────────────────────────────────────────────────────────────────┘Data Flow
Section titled “Data Flow”Publisher (Ingest) │ ▼StreamManager.create_publisher(stream_path) │ ├──▶ VideoTrack ──▶ RingBuffer (256 slots, lock-free) │ │ ├──▶ AudioTrack ──▶ RingBuffer (64 slots, lock-free) │ │ │ ▼ │ Dispatcher / DispatcherPool │ │ │ │ │ ▼ ▼ ▼ │ Queue 1 Queue 2 Queue N │ (bounded) (bounded) (bounded) │ │ │ │ └──▶ WaitQueue ▼ ▼ ▼ (Wait List) Subscriber Subscriber Subscriber (Playback) (Playback) (Playback)Core Modules
Section titled “Core Modules”The core modules are located in src/core/ and are responsible for the underlying data structures and processing logic of the streaming engine:
| Module | File | Responsibility |
|---|---|---|
| buffer | buffer.rs | Lock-free SPMC ring buffer for frame storage |
| frame | frame.rs | AVFrame audio/video frame data structure |
| track | track.rs | Audio/video track management (VideoTrack / AudioTrack) |
| publisher | publisher.rs | Publisher, manages tracks and subscriber list |
| subscriber | subscriber.rs | Subscriber, consumes frame data from RingBuffer |
| dispatcher | dispatcher.rs | Frame dispatcher, single read broadcasts to all subscribers |
| pool | pool.rs | Object pool (BytesPool, ObjectPool, ThreadLocal pool) |
| task | task.rs | Hierarchical task system with cascading cancellation |
| proxy | proxy.rs | Pull/Push proxy (Pull Proxy / Push Proxy) |
| recorder | recorder.rs | Stream recording framework (FLV / MP4 / fMP4 / HLS) |
| transformer | transformer.rs | Stream transformer (subscribe source → process → publish new stream) |
| playback | playback.rs | Playback speed control and timestamp scaling |
| storage | storage.rs | Async storage trait (io_uring ready) |
Crate Structure
Section titled “Crate Structure”Monibuca V6 uses a Cargo Workspace to organize code, split into multiple independent crates:
monibuca/ # Main crate (engine + binary)├── src/│ ├── core/ # Core data structures│ ├── manager/ # StreamManager / PluginManager│ ├── config/ # Configuration management│ ├── grpc/ # gRPC API│ └── room/ # Built-in room service├── crates/│ ├── monibuca-codec/ # codec crate — codecs + enums + traits│ ├── monibuca-sdk/ # SDK crate — plugin development SDK│ ├── monibuca-sdk-macros/ # SDK proc macros│ ├── m7s-config-framework/ # Configuration framework│ └── m7s-config-macros/ # Configuration framework macros└── plugins/ # 25 plugin crates ├── rtmp/ ├── rtsp/ ├── flv/ ├── hls/ ├── webrtc/ └── ...Crate Dependency Graph
Section titled “Crate Dependency Graph”monibuca-codec ◀── Bottom layer, zero dependencies on other monibuca crates ▲ │monibuca-sdk ◀── The sole contract layer for plugin development ▲ │monibuca (engine) ◀── Main engine crate ▲ │plugins/* ◀── All plugins depend only on the SDK- codec: Defines all shared types — AVFrame, VideoCodec, AudioCodec, VideoFrameType, trait interfaces (PublisherApi / SubscriberApi / StreamManagerApi)
- SDK: Wraps codec and provides plugin registration, HTTP routing, config schema, and other development tools
- Main crate: Engine implementation, containing core logic such as StreamManager, Dispatcher, RingBuffer, etc.
- plugins/: Protocol and feature plugins, depending only on the SDK crate
Plugin System Architecture
Section titled “Plugin System Architecture”Monibuca V6 supports three plugin loading modes:
| Mode | Feature Flag | Characteristics |
|---|---|---|
| Static compilation | static-plugins | Linked at compile time, best performance, default mode |
| Dynamic loading | dynamic-plugins | .so/.dylib/.dll loaded at runtime |
| WASM sandbox | — | Isolated execution, highest security |
Static plugins are selectively compiled via Cargo Feature Flags:
[features]default = ["static-plugins"]rtmp = ["dep:plugin-rtmp"]rtsp = ["dep:plugin-rtsp"]webrtc = ["dep:plugin-webrtc"]all-plugins = ["rtmp", "rtsp", "flv", "hls", "webrtc", "srt", ...] # default full set (no rsmpeg)all-plugins-rsmpeg = ["all-plugins", "rsmpeg"] # full set with FFmpeg library bindingsTechnology Stack
Section titled “Technology Stack”| Component | Library | Purpose |
|---|---|---|
| Async runtime | Tokio | Event-driven concurrency |
| Mutex | parking_lot | High-performance Mutex / RwLock |
| Concurrent hash map | DashMap | Lock-free stream registry |
| Atomic pointer swap | ArcSwap | Lock-free IDR list, subscriber list |
| QUIC transport | Quinn | WebTransport / QUIC protocol support |
| Zero-copy bytes | Bytes | Zero-copy frame data sharing |
| WebRTC | rustrtc | WebRTC protocol stack |
| gRPC | Tonic | API service |
| Database | SQLx | Recording index, configuration persistence |
| Serialization | Serde + serde_json/serde_yaml | Configuration and API data formats |
Performance Design Principles
Section titled “Performance Design Principles”- Lock-free first: RingBuffer write operations use
fetch_addatomic instructions, read operations achieve lock-free access throughArcSwap - Zero-copy: Frame data is shared via
Arc<AVFrame>, no data copying between subscribers - Single-read broadcast: Dispatcher reads frame data from the RingBuffer only once, then broadcasts to all subscribers
- Backpressure control: Uses bounded channels, slow subscribers drop frames instead of blocking other subscribers
- Object pool reuse: BytesPool and ThreadLocal pools reduce memory allocation on hot paths