videocall-codecs: Jitter Buffer & Decoder
This crate is a core component of the videocall.rs project. It provides a high-fidelity, cross-platform video decoder and jitter buffer, implemented in pure Rust.
Vision
Currently focused on high-quality video decoding and jitter buffering, videocall-codecs is expanding to become a comprehensive multimedia codec solution. Audio support is coming soon - we're actively working on integrating audio codecs (Opus, AAC) alongside our existing video capabilities to provide a unified, cross-platform audio/video processing pipeline.
Our roadmap includes:
- Audio Codec Integration: Opus and AAC support with the same cross-platform design
- Unified Jitter Buffer: Combined audio/video synchronization
- Enhanced Web Support: Audio processing in Web Workers alongside video
- Real-time Audio Processing: Low-latency audio decoding optimized for live streaming
Features
- Cross-platform: Works on native (libvpx) and WASM (WebCodecs) targets
- Built-in Jitter Buffer: Automatic frame reordering, gap detection, and adaptive playout delay
- Ergonomic API: Simple
push_frame()interface hides complexity - VP9 Codec Support: High-quality video compression
- Real-time Optimized: Designed for low-latency video streaming
- Web-ready: Easy WASM integration with automatic Web Worker setup
Quick Start
Native Usage
use ;
let decoder = new;
let video_frame = VideoFrame ;
decoder.decode;
Web/WASM Usage
# 1. Build for web
# 2. Install in your project
// 3. Use in JavaScript
import init from './pkg/videocall_codecs.js';
await ;
const canvas = document.;
const ctx = canvas.;
const decoder = ;
// Push frames from your video stream
decoder.;
Web Worker Setup (WASM)
For WASM builds, the decoder runs in a Web Worker for better performance. Add this to your index.html:
<!-- Compile the worker -->
<!-- Runtime link for decoder -->
Architecture
Jitter Buffer
The built-in jitter buffer automatically handles:
- Frame Reordering: Out-of-order frames are buffered and played in sequence
- Gap Recovery: Jumps to keyframes when frames are lost
- Adaptive Delay: Adjusts playout delay based on network jitter
- Buffer Management: Prevents buffer overflow with configurable limits
Cross-Platform Design
┌─────────────────┐ ┌───────────────────┐ ┌─────────────────┐
│ Your App │ │ videocall-codecs │ │ Platform │
│ │ │ │ │ │
│ decoder.decode()│───▶│ JitterBuffer │───▶│ Native: libvpx │
│ │ │ FrameReordering │ │ WASM: WebCodecs │
│ │ │ AdaptiveDelay │ │ │
└─────────────────┘ └───────────────────┘ └─────────────────┘
The crate implements a trait-based abstraction that allows the same jitter buffer logic to work across both native and WASM targets, with platform-specific decoder implementations handling the actual video decoding.
API Reference
Core Types
Platform APIs
Native:
let decoder = new;
WASM:
const decoder = ;
Framework Integration
React Example
import { useEffect, useRef } from 'react';
import init, { WasmDecoder, VideoCodec } from 'videocall-codecs';
export const VideoPlayer = ({ websocketUrl }: { websocketUrl: string }) => {
const canvasRef = useRef(null);
useEffect(() => {
const initDecoder = async () => {
await init();
const canvas = canvasRef.current!;
const ctx = canvas.getContext('2d')!;
const decoder = new WasmDecoder(VideoCodec.VP9, (videoFrame) => {
ctx.drawImage(videoFrame, 0, 0, canvas.width, canvas.height);
videoFrame.close();
});
// Connect WebSocket and handle frames...
};
initDecoder();
}, [websocketUrl]);
return ;
};
Configuration
Jitter Buffer Settings
const MIN_PLAYOUT_DELAY_MS: f64 = 10.0;
const MAX_PLAYOUT_DELAY_MS: f64 = 500.0;
const JITTER_MULTIPLIER: f64 = 3.0;
const MAX_BUFFER_SIZE: usize = 200;
Cargo Features
[]
= ["native"]
= ["libvpx-sys"]
= ["wasm-bindgen", "web-sys", "js-sys", "wasm-bindgen-futures"]
Troubleshooting
WASM import issues:
// Always initialize first
import init from './pkg/videocall_codecs.js';
await ;
Memory leaks:
// Always close VideoFrame objects
decoder = ;
Frame types:
// Use exact strings
decoder.;
Performance Tips
- Always call
videoFrame.close()in WASM to prevent memory leaks - Use Web Workers: Automatically enabled when available
- Send keyframes regularly for gap recovery
- Use monotonic sequence numbers for proper ordering
Testing
License
Licensed under either of Apache License, Version 2.0 or MIT license at your option.