Overview
wink-rtpdump is a modern, high-performance RTP/RTCP analysis toolkit built for professional streaming workflows. Inspired by Columbia University's legendary rtptools, it's been completely reimagined and rebuilt from the ground up in Go.
Why We Built This
The streaming world has evolved dramatically since the original rtptools:
- 4K and 8K video pushes 50-100+ Mbps through RTP
- Multi-SSRC streams carry audio, video, and multiple simulcast layers
- WebRTC brought RTP to billions of browsers with new header extensions
- Cloud-native workflows demand JSON output for monitoring pipelines
- CI/CD integration requires programmatic exit codes and thresholds
Key Capabilities
| Command |
Purpose |
inspect |
Analyze RTP/RTCP with real-time statistics and health indicators |
pipe |
Extract payload for ffmpeg/ffplay with optional jitter buffering |
record |
Capture to PCAPNG, rtpdump, or JSONL formats |
replay |
Playback recordings with timing control and looping |
relay |
Forward with jitter buffer and packet reordering |
sdp |
Generate SDP from observed stream characteristics |
Enterprise Integration
wink-rtpdump's jitter buffer technology is built into WINK Forge and WINK Media Router. Enterprise customers get this functionality integrated directly into their streaming infrastructure with web-based management, SNMP monitoring, and 24/7 support.
Installation
Pre-built Binaries
Download the latest release for your platform - single binary, zero dependencies:
- Linux (x86_64, arm64)
- macOS (Intel x64, Apple Silicon arm64)
- Windows (x86_64, arm64)
Verify Installation
$ chmod +x wink-rtpdump-*
$ ./wink-rtpdump version
wink-rtpdump 1.0.0
Build Date: 2023-06-15
Go Version: go1.20.5
OS/Arch: darwin/arm64
Quick Start
Analyze a Live Stream
$ wink-rtpdump inspect udp://0.0.0.0:5004
$ wink-rtpdump inspect udp://239.1.1.1:5004 --iface eth0
$ wink-rtpdump inspect udp://0.0.0.0:5004 --output json --duration 60s
Pipe to FFmpeg/FFplay
$ wink-rtpdump pipe udp://0.0.0.0:5004 --payload | ffplay -i -
$ wink-rtpdump pipe udp://0.0.0.0:5004 --payload --jitter-buffer 200 | ffplay -i -
$ wink-rtpdump pipe udp://0.0.0.0:5004 --payload --jitter-buffer 1000 | \
ffmpeg -f mpegts -i pipe:0 -c copy recording.ts
Record and Replay
$ wink-rtpdump record udp://0.0.0.0:5004 --output-pcap capture.pcapng
$ wink-rtpdump replay capture.pcapng --dest 127.0.0.1:5004 --speed 2.0 --loop
Fix a Problematic Stream
$ wink-rtpdump relay udp://0.0.0.0:5004 127.0.0.1:6004 --jitter-buffer 300
Understanding Jitter Buffering
What is Jitter?
Jitter is the variation in packet arrival times. Even if packets are sent at regular 20ms intervals, they may arrive with timing variations due to network conditions:
Sent: |--20ms--|--20ms--|--20ms--|--20ms--|--20ms--|
[1] [2] [3] [4] [5]
Received: |--18ms--|--25ms--|--15ms--|--22ms--|--20ms--|
[1] [2] [3] [4] [5]
-2ms +5ms -5ms +2ms 0ms ← Jitter variation
wink-rtpdump calculates RFC 3550 interarrival jitter - a smoothed estimate of this variation.
| Jitter |
Quality |
Notes |
| < 5ms |
Excellent |
LAN or same datacenter |
| 5-20ms |
Good |
Well-provisioned networks |
| 20-50ms |
Acceptable |
May need buffering |
| > 50ms |
Problematic |
Definitely needs buffering |
What is Packet Reordering?
Out-of-order packets arrive in the wrong sequence. This is surprisingly common on the internet:
Sent: [1] [2] [3] [4] [5] [6] [7] [8]
| | | | | | | |
v v v v v v v v
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~ Internet: Multi-path routing ~~~~~~
~~~ Load balancers, QoS policies ~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | | | | | | |
v v v v v v v v
Received: [1] [3] [2] [5] [4] [7] [6] [8] ← Out of order!
Causes:
- Multi-path routing (packets take different paths)
- Load balancer packet distribution
- QoS priority differences
- Link-layer retransmissions
- Cellular network handoffs
Effects on video:
- H.264/H.265 decoders lose reference frames → macroblocking
- Audio gets clicks and pops
- MPEG-TS demuxers lose sync
- Players freeze or crash
How Our Jitter Buffer Fixes It
wink-rtpdump Jitter Buffer
┌─────────────────────────────────┐
Incoming (messy): │ │ Outgoing (perfect):
│ ┌─────────────────────┐ │
[1][3][2][5][4] ──▶│ │ Priority Queue │ │──▶ [1][2][3][4][5]
│ │ (Min-Heap by Seq) │ │
│ │ │ │
│ │ [2] ─┐ │ │
│ │ [3] ─┼─ sorted │ │
│ │ [4] ─┤ │ │
│ │ [5] ─┘ │ │
│ └─────────────────────┘ │
│ │
│ Waits up to deadline for │
│ missing packets, then emits │
│ in correct sequence order │
└─────────────────────────────────┘
The jitter buffer:
- Extends 16-bit sequences to 32-bit - RTP sequence numbers wrap at 65535. Our extended sequence tracking handles wraps seamlessly, even across long recordings.
- Buffers intelligently - Packets are held in a priority queue sorted by sequence number. The buffer waits for out-of-order packets up to a configurable deadline.
- Emits in perfect order - When the deadline expires or the next expected sequence arrives, packets flow out in correct order.
- Handles edge cases - Duplicate detection, late arrival decisions, gap handling, SSRC changes.
- Scales per-SSRC - Each synchronization source gets its own buffer. Audio and video don't interfere.
Real Results: We've fixed streams with 5%+ out-of-order rates that were completely unwatchable. Networks that caused constant glitches become stable. Satellite uplinks with terrible jitter? Handled.
Command Reference
inspect - Analyze RTP/RTCP Traffic
Real-time analysis with per-SSRC statistics, color-coded health indicators, and threshold-based exit codes.
$ wink-rtpdump inspect <source> [flags]
| Flag |
Default |
Description |
--duration |
0 (infinite) |
Analysis duration (e.g., 30s, 5m) |
--interval |
500ms |
Display update interval |
--output |
console |
Output format: console or json |
--iface |
(auto) |
Network interface for multicast |
--buffer-size |
2MB |
UDP receive buffer size |
--error-threshold |
0 |
Exit code 2 if loss % exceeds threshold |
--jitter-threshold |
0 |
Exit code 3 if jitter (ms) exceeds threshold |
--throughput-threshold |
0 |
Exit code 4 if kbps below threshold |
--quiet |
false |
Final summary only (no live updates) |
--no-ansi |
false |
Disable colors in output |
Example Output
WINK RTP Dump v1.0.0
Source: udp://239.1.1.1:5004
Elapsed: 45.2s | RTP: 13,456 pkts | RTCP: 24 pkts | 3 SSRCs
Sessions:
────────────────────────────────────────────────────────────────────────────────
SSRC PT bitrate pps loss% ooo% dup% jitter drift rtcp?
────────────────────────────────────────────────────────────────────────────────
0x12345678 96 4.2 Mbps 45.1 0.02 0.00 0.00 2.3ms stable yes
0xABCDEF01 111 128 kbps 50.0 0.00 0.01 0.00 0.8ms stable yes
0x87654321 96 4.1 Mbps 45.0 0.15 0.02 0.00 3.1ms +12ppm yes
────────────────────────────────────────────────────────────────────────────────
Summary: 3 SSRCs | Avg Loss: 0.06% | Avg Jitter: 2.1ms | Total: 8.4 Mbps
pipe - Extract for External Tools
Stream RTP payload to stdout for processing by ffmpeg, ffplay, GStreamer, or custom tools.
$ wink-rtpdump pipe <source> [flags]
| Flag |
Default |
Description |
--payload |
false |
Output payload only (strip RTP headers) |
--jitter-buffer |
0 |
Jitter buffer latency in milliseconds |
--reorder-window |
64 |
Maximum packets to hold for reordering |
--ssrc |
(all) |
Filter by specific SSRC (hex) |
--pt |
-1 (all) |
Filter by payload type |
record - Capture to File
$ wink-rtpdump record <source> [flags]
| Flag |
Description |
--output-pcap |
PCAPNG file (Wireshark compatible) |
--output-rtpdump |
Legacy rtpdump format |
--output-jsonl |
JSONL per-packet log |
--duration |
Recording duration |
--rotate |
File rotation interval |
relay - Forward with Jitter Buffer
This is where the jitter buffer really shines. Transform a problematic incoming stream into a clean output.
$ wink-rtpdump relay <input> <output> [flags]
| Flag |
Default |
Description |
--jitter-buffer |
100 |
Buffer latency in milliseconds |
--reorder-window |
64 |
Packets to buffer for reordering |
--drop-late |
true |
Drop packets arriving after deadline |
--mirror |
false |
Output both raw and buffered streams |
replay - Playback Recordings
$ wink-rtpdump replay <file> --dest <host:port> [flags]
| Flag |
Default |
Description |
--dest |
(required) |
UDP destination host:port |
--pacing |
original |
Timing mode |
--speed |
1.0 |
Speed multiplier |
--loop |
false |
Loop playback continuously |
sdp - Generate SDP
Observe a stream and generate a minimal SDP description.
$ wink-rtpdump sdp udp://0.0.0.0:5004 --duration 5s > stream.sdp
FFmpeg Integration
wink-rtpdump is designed to work seamlessly with FFmpeg. Here are tested, production-ready examples.
Basic Playback Pipeline
$ wink-rtpdump pipe udp://0.0.0.0:5004 --payload | \
ffplay -f mpegts -i pipe:0
$ wink-rtpdump pipe udp://0.0.0.0:5004 --payload --jitter-buffer 200 | \
ffplay -f mpegts -i pipe:0 -fflags nobuffer
Recording Pipeline
$ wink-rtpdump pipe udp://0.0.0.0:5004 --payload --jitter-buffer 500 | \
ffmpeg -f mpegts -i pipe:0 -c copy -t 10 output.mp4
$ wink-rtpdump pipe udp://0.0.0.0:5004 --payload \
--jitter-buffer 1000 --reorder-window 512 | \
ffmpeg -f mpegts -i pipe:0 -c copy archive.ts
Transcoding Pipeline
$ wink-rtpdump pipe udp://0.0.0.0:5004 --payload --jitter-buffer 300 | \
ffmpeg -f mpegts -i pipe:0 \
-c:v libx264 -preset fast -crf 23 \
-c:a aac -b:a 128k \
-f hls -hls_time 4 -hls_list_size 5 \
/var/www/html/stream/playlist.m3u8
$ wink-rtpdump pipe udp://0.0.0.0:5004 --payload --jitter-buffer 150 | \
ffmpeg -f mpegts -i pipe:0 \
-c:v libx264 -preset ultrafast -tune zerolatency \
-c:a aac \
-f flv rtmp://live.example.com/app/stream
Sending Test Streams
$ ffmpeg -re -i testvideo.mp4 \
-c:v libx264 -preset ultrafast -tune zerolatency \
-x264opts "repeat-headers=1" -g 30 \
-c:a aac \
-f rtp_mpegts rtp://127.0.0.1:5004
$ wink-rtpdump pipe udp://0.0.0.0:5004 --payload --jitter-buffer 200 | \
ffplay -f mpegts -i pipe:0
Pro Tip: Always use -x264opts "repeat-headers=1" when encoding H.264 for RTP. This ensures SPS/PPS are repeated at keyframes, so receivers joining mid-stream can start decoding immediately.
Multi-Stream Recording
$ for port in 5004 5006 5008 5010; do
wink-rtpdump pipe udp://0.0.0.0:$port --payload --jitter-buffer 500 | \
ffmpeg -f mpegts -i pipe:0 -c copy camera_${port}.ts &
done
$ wait
Analysis Pipeline
$ wink-rtpdump pipe udp://0.0.0.0:5004 --payload --jitter-buffer 200 | \
tee >(ffmpeg -f mpegts -i pipe:0 -c copy recording.ts) | \
ffprobe -f mpegts -i pipe:0 -show_streams
Handling "non-existing PPS" Errors
If you see FFmpeg errors like non-existing PPS or no frame!, it means you joined an H.264 stream mid-flight before receiving codec parameters:
Solutions:
- Start the receiver before the sender
- Have the sender use
-x264opts "repeat-headers=1"
- Wait for the next keyframe (may take a few seconds)
- Use a packager that always includes SPS/PPS in the stream
Real-World Examples
Remote Sports Broadcast
Scenario: Camera feeds coming over bonded cellular from a stadium 500 miles away. Network path traverses three ISPs with congestion during peak hours. Viewers seeing constant glitches and macroblocking.
Solution:
$ wink-rtpdump inspect udp://0.0.0.0:5004 --duration 30s
# You see: loss 0.1%, ooo 3.2%, jitter 45ms - the reordering is killing you
$ wink-rtpdump relay udp://0.0.0.0:5004 127.0.0.1:6004 \
--jitter-buffer 300 --reorder-window 256
The 300ms buffer adds barely-noticeable delay but fixes the reordering. Production looks professional again.
Satellite Contribution Feed
Scenario: News organization receives satellite feeds from correspondents worldwide. Uplinks have high latency and variable jitter due to weather and orbital mechanics. Cuts to satellite reporters are risky - video sometimes freezes.
Solution:
$ wink-rtpdump relay udp://0.0.0.0:5004 127.0.0.1:6004 --jitter-buffer 500
WebRTC Quality Monitoring
Scenario: Video conferencing platform needs to monitor call quality across thousands of sessions for SLA compliance. Need quantitative per-SSRC metrics since each call has multiple streams.
Solution:
$ wink-rtpdump inspect udp://0.0.0.0:$PORT \
--output json \
--duration 60s \
--error-threshold 1.0 \
--jitter-threshold 50 \
> /var/log/rtpstats/session_$ID.json
Live Event Pre-Show Validation
Scenario: Major concert stream with 100,000 viewers waiting. 5 minutes before showtime. Need confidence all feeds are healthy.
Solution:
$ for feed in video1 video2 audio1 audio2; do
wink-rtpdump inspect udp://0.0.0.0:${PORTS[$feed]} \
--duration 10s \
--error-threshold 0.1 \
--jitter-threshold 20 \
--quiet
if [ $? -ne 0 ]; then
echo "ALERT: $feed failed quality check!"
else
echo "OK: $feed passed"
fi
done
IPTV Headend Monitoring
Scenario: IPTV system with 500 multicast channels. Need 24/7 monitoring for quality degradation. Commercial monitoring systems cost $50,000+.
Solution:
$ while read channel; do
wink-rtpdump inspect "udp://$channel" \
--output json \
--duration 60s \
--no-ansi \
>> /var/log/iptv/channel_${channel//\//_}.jsonl &
done < channels.txt
Hotel WiFi Streaming Fix
Scenario: Traveling content creator needs to stream from hotel room with terrible WiFi. Packets are being reordered constantly, breaking CDN ingest.
Solution:
$ wink-rtpdump pipe udp://0.0.0.0:5004 --payload --jitter-buffer 500 | \
ffmpeg -f mpegts -i pipe:0 -c copy -f flv rtmp://cdn.example.com/live/stream
Archive Digitization
Scenario: Broadcaster digitizing decades of tape archives. Old equipment outputs SDI converted to RTP, but has timing issues causing occasional frame drops.
Solution:
$ wink-rtpdump pipe udp://0.0.0.0:5004 --payload \
--jitter-buffer 500 --reorder-window 256 | \
ffmpeg -f mpegts -i pipe:0 -c:v libx264 -crf 18 -c:a flac archive_master.mkv
Enterprise Integration
Built Into WINK Products
The jitter buffering technology in wink-rtpdump is the same engine that powers our enterprise products. If you need managed, always-on jitter buffering with web UI, SNMP monitoring, and professional support:
- WINK Forge - Enterprise transcoding platform with built-in jitter buffer for problematic source streams
- WINK Media Router - Video distribution platform with per-stream jitter buffering and packet loss recovery
WINK Forge Integration
WINK Forge includes jitter buffering as part of its input processing pipeline. When ingesting RTP streams from cameras or contribution feeds:
┌─────────────┐ ┌─────────────────────────────────────────────┐ ┌─────────────┐
│ Camera │ │ WINK Forge │ │ Output │
│ (RTP out) │────▶│ ┌────────────┐ ┌────────┐ ┌──────────┐ │────▶│ (HLS/RTMP/ │
│ │ │ │ Jitter │ │Transcode│ │ Package │ │ │ RTSP) │
└─────────────┘ │ │ Buffer │ │ Engine │ │ │ │ └─────────────┘
│ └────────────┘ └────────┘ └──────────┘ │
│ │
│ Web UI: Configure buffer per input stream │
└─────────────────────────────────────────────┘
Configuration is done through the web interface - no command line needed. Set jitter buffer depth per input, monitor packet statistics in real-time, and get alerts when quality degrades.
WINK Media Router Integration
WINK Media Router can apply jitter buffering when relaying streams between systems:
┌─────────────┐ ┌───────────────────────────────────────────────────┐ ┌─────────────┐
│ Source │ │ WINK Media Router │ │ Destination │
│ (VMS/NVR) │────▶│ ┌────────────┐ ┌──────────┐ ┌──────────────┐ │────▶│ (VMS/Web/ │
│ │ │ │ Jitter │ │ Protocol │ │ Auth/ACL │ │ │ Mobile) │
└─────────────┘ │ │ Buffer │ │ Convert │ │ │ │ └─────────────┘
│ └────────────┘ └──────────┘ └──────────────┘ │
│ │
│ SNMP: Per-stream loss/jitter metrics available │
└───────────────────────────────────────────────────┘
Ideal for multi-agency video sharing where source streams traverse unpredictable network paths. Each receiving agency gets a clean, buffered stream regardless of source quality.
Enterprise Features Not in CLI Tool:
- Web-based configuration and monitoring
- SNMP traps for quality alerts
- Redundant input failover
- Per-stream statistics logging
- Integration with existing monitoring systems
- 24/7 technical support
Contact us to discuss enterprise deployment options.
Jitter Buffer Settings Guide
Quick Reference
| Use Case |
--jitter-buffer |
--reorder-window |
| Live viewing (minimal delay) |
50-100ms |
32-64 |
| Standard streaming |
100-200ms |
64-128 |
| Challenging networks |
200-400ms |
128-256 |
| Recording (latency irrelevant) |
500-1000ms |
256-512 |
By Network Type
| Network |
Recommended Buffer |
| Local LAN |
50ms |
| Same datacenter |
50-100ms |
| Same region CDN |
100-150ms |
| Cross-region |
150-250ms |
| Satellite uplink |
300-500ms |
| Mobile/cellular |
200-400ms |
| Terrible hotel WiFi |
500ms+ |
What Buffering Cannot Fix
- Packet loss - Lost packets are gone forever. Buffering can't create data that never arrived.
- Encoder problems - Garbage in, garbage out. If the source is corrupt, buffering won't help.
- Clock drift - Sender timing issues persist through the buffer.
- Severe congestion - If 10% is lost, get a better network path.
Exit Codes
wink-rtpdump uses exit codes for CI/CD integration and automated monitoring:
| Code |
Name |
Description |
0 |
Success |
Analysis completed, all thresholds passed |
2 |
Loss Exceeded |
Packet loss exceeded --error-threshold |
3 |
Jitter Exceeded |
Jitter exceeded --jitter-threshold |
4 |
Throughput Low |
Throughput below --throughput-threshold |
5 |
No Packets |
No RTP packets received |
6 |
Parse Error |
Could not parse input |
7 |
Network Error |
Could not bind to port or join multicast |
CI/CD Integration Example
wink-rtpdump inspect udp://0.0.0.0:5004 \
--duration 60s \
--error-threshold 0.5 \
--jitter-threshold 30 \
--throughput-threshold 1000 \
--output json > /tmp/stream-report.json
EXIT_CODE=$?
case $EXIT_CODE in
0) echo "Stream healthy - all checks passed" ;;
2) echo "FAIL: Packet loss exceeded 0.5%" ;;
3) echo "FAIL: Jitter exceeded 30ms" ;;
4) echo "FAIL: Throughput below 1000 kbps" ;;
5) echo "FAIL: No RTP packets received" ;;
*) echo "FAIL: Unexpected error $EXIT_CODE" ;;
esac
exit $EXIT_CODE
Troubleshooting
No Packets Received
- Check firewall allows UDP on the port
- For multicast, verify
--iface is correct
- Confirm source is actually sending
- Try
tcpdump -i any port 5004 to verify traffic
High Packet Loss
- Check network path:
ping, traceroute, mtr
- Look for interface errors:
ip -s link
- Check CPU load on sender/receiver
- Consider QoS or dedicated network path
Jitter Buffer Not Helping
- If
loss% is high, packets are lost not just delayed - buffering can't help
- If
ooo% is still high, try larger --jitter-buffer
- Problem might be at the source (encoder/camera)
FFplay Stuttering
- Increase
--jitter-buffer
- Ensure
--payload flag is used for MPEG-TS
- Add ffplay buffering:
ffplay -i - -fflags nobuffer
"non-existing PPS" Errors
You joined an H.264 stream mid-flight:
- Start receiver before sender
- Have sender use
-x264opts "repeat-headers=1"
- Wait for next keyframe (may take a few seconds)
High CPU Usage
- Check if you're accidentally decoding video (shouldn't be needed)
- Reduce
--reorder-window if set very high
- For 100+ Mbps streams, ensure adequate CPU