Skip to main content

Overview

Multi-stream mode allows you to monitor multiple RTSP cameras simultaneously. Each stream:
  • Runs in its own dedicated thread
  • Has independent person detection
  • Saves to a separate output directory
  • Can be viewed together in a grid display
Multi-stream mode is designed for 2-16 cameras. For larger deployments, consider running multiple instances with different camera groups.

Basic Usage

Two Methods for Specifying Streams

Pass URLs directly as command arguments:
Use quotes around each URL, especially if they contain special characters.

Command Options

list
One or more RTSP stream URLs separated by spaces
string
Path to text file containing RTSP URLs (one per line)
choice
required
Save mode: image for snapshots or video for clips
flag
Enable grid display window showing all streams

RTSP URL File Format

Create a text file with one RTSP URL per line:
rtsp_streams.txt
File parsing (main.py:119-124):
File format rules:
  • One URL per line
  • Blank lines are ignored
  • Lines starting with # are comments
  • Leading/trailing whitespace is trimmed

Grid Display

When --display is enabled, all streams appear in a single composited window.

Enable Grid Display

Grid Layout

Streams are automatically arranged in a grid: Grid examples:
Grid features:
  • Each stream shows person count and entry counter
  • Green bounding boxes around detected persons
  • Confidence scores displayed
  • Streams update independently
  • Press ‘q’ to quit

Without Display (Headless)

Omit --display to run without GUI (headless servers):
Behavior:
  • No display window
  • Lower resource usage
  • Still processes all streams
  • Saves output files normally
  • Logs to console

Threading Architecture

Each stream processes independently in its own thread.

Thread Creation

From multi_stream_manager.py:71-80:
Key characteristics:

Daemon Threads

Threads are daemon threads - they terminate when main program exits.

Independent Processing

Each stream has its own connection, detection loop, and reconnection logic.

Shared Detector

All threads share a single PersonDetector instance with thread-safe inference.

Separate Outputs

Each stream saves to its own stream_<id>/ directory.

Thread-Safe Detection

The PersonDetector uses a lock to ensure only one thread runs inference at a time. From person_detector.py:228-244:
Why thread-safety matters:
  • OpenCV’s DNN module is not thread-safe
  • Multiple threads calling net.forward() simultaneously causes crashes
  • Lock ensures sequential inference
  • Other operations (frame reading, saving) remain parallel
Performance impact: With many streams, inference becomes a bottleneck. GPU acceleration helps significantly.

Thread Monitoring

The main thread waits for all worker threads: From multi_stream_manager.py:82-94:
Termination triggers:
  1. User presses ‘q’ (closes display window)
  2. User presses Ctrl+C
  3. All streams disconnect and exhaust retries

Output Organization

Multi-stream mode creates a sub-directory for each stream.

Directory Structure

Stream ID Assignment

Stream IDs are assigned based on input method:
Auto-numbered starting from 1:
From multi_stream_manager.py:56-59:

Directory Creation

From stream_processor.py:55-58:
Directories are created automatically when the first person is detected in each stream.

Performance Considerations

CPU/GPU Bottlenecks

Inference bottleneck:
  • Thread-safe lock means only one detection at a time
  • With 8 streams and 100ms inference time:
    • Each stream gets detection every 800ms minimum
    • Plus frame_skip delays
Solutions:
1

Enable GPU acceleration

CUDA-enabled OpenCV reduces inference from ~100ms to ~10ms.See GPU Acceleration Guide
2

Increase frame_skip

Process fewer frames per stream:
3

Adjust thresholds

Higher thresholds = fewer detections = less saving overhead:
4

Disable display for more streams

Display rendering adds overhead:

Memory Usage

Per-stream overhead:
  • Frame buffer: ~6 MB (1920×1080 RGB)
  • Video writer buffer: ~10-20 MB
  • Network buffers: ~5 MB
  • Total per stream: ~20-30 MB
Example:
  • 16 streams: ~400 MB
  • Plus model weights: ~250 MB (YOLOv4)
  • Total: ~650 MB baseline
Monitor memory with:

Network Bandwidth

Bandwidth calculation:
Ensure your network can handle aggregate bandwidth, especially on WiFi or shared switches.

Scaling Guidelines

Console Output

Understanding multi-stream console output:
Key indicators:
  • [Stream N] prefix identifies which stream each message is from
  • Thread start messages confirm all streams launched
  • Connection messages show parallel connection attempts
  • Detection events include stream ID and bounding box coordinates
  • Final summary shows per-stream statistics

Real-World Examples

Example 1: Retail Store (4 Cameras)

Setup:
  • Front entrance
  • Back entrance
  • Checkout area
  • Stock room
cameras.txt
Result:
  • Grid display shows all 4 cameras
  • Snapshot saved when person enters each area
  • Higher thresholds reduce false positives

Example 2: Warehouse (12 Cameras)

Setup:
  • Loading docks (4)
  • Main aisles (6)
  • Offices (2)
Optimization:
  • No display (12 streams = too many for useful grid)
  • Higher frame_skip (30 = 1 fps) for performance
  • Video mode captures full activity
  • Run on server with GPU

Example 3: Office Building (8 Cameras)

Setup:
  • Lobby
  • Elevator banks (3)
  • Conference rooms (2)
  • Server room
  • Parking garage
Configuration:
  • Balanced settings
  • Video clips for security review
  • Grid display for monitoring
  • Standard detection frequency

Troubleshooting

Issue: One bad URL causes problemsSolution: Threads are independent. A failing stream won’t crash others, but will keep retrying:
Comment out the bad URL in your file:
Issue: Some tiles frozen or blackPossible causes:
  • Stream connection issue
  • Thread crashed
  • Very slow inference
Debug: Check console for [Stream N] messages. Missing messages indicate that stream has issues.
Issue: Long delays between detectionsCause: Thread-safe inference lock is bottleneckSolutions:
  1. Enable GPU acceleration:
    See GPU Acceleration
  2. Increase frame_skip:
  3. Reduce number of streams: Split into multiple instances
Error:
Solutions:
  1. Reduce number of streams
  2. Disable display: --display adds overhead
  3. Check available RAM:
  4. Use lower resolution streams (configure at camera)
Issue: ‘q’ key doesn’t stop processingCause: Display window must have focusSolution:
  • Click on the grid window first
  • Then press ‘q’
  • Or use Ctrl+C in terminal

Best Practices

Use URL Files

Easier to manage, edit, and version control than command-line lists.

Test Streams First

Verify each RTSP URL works with VLC before adding to multi-stream setup.

Start Small, Scale Up

Test with 2-4 streams first, then add more as you tune performance.

Monitor System Resources

Use htop or similar to watch CPU, RAM, and network usage.

Enable GPU for >4 Streams

GPU acceleration is essential for processing many streams efficiently.

Label Your Streams

Use comments in URL file to document which camera is which.

Next Steps

GPU Acceleration

Essential for multi-stream performance

Configuration Tuning

Optimize settings for your camera setup

Single Stream Guide

Understand single-stream processing

Model Setup

Configure detection models