The system runs as multiple cooperating processes communicating through shared memory:
Camera 0 ──> capture.exe 0 ──┐
Camera 1 ──> capture.exe 1 ──┼──> Shared Memory (16GB) ──> videogen.exe ──> viewer.exe
Camera 2 ──> capture.exe 2 ──┘ ^ |
| v
motion.exe 0/1/2 Output Files
(reads feeds, (H.264 MP4)
writes flags)
controller.exe: launches and monitors all processes
All processes access a single large shared memory region (~16GB) containing:
Each feed has 3 channels (active, latest, ready) with 520-frame circular buffers. Each frame contains:
Double-buffered output for the viewer. While one buffer is being written by videogen, the viewer reads the other.
| Component | Calculation | Size |
|---|---|---|
| Feed data | 3 feeds x 3 channels x 520 frames x 2.3MB | ~10.8 GB |
| Output data | 2 feeds x 520 frames x 2.3MB | ~2.4 GB |
| Control/metadata | Headers, indices, flags | ~50 MB |
| Total | ~13.3 GB |
Processes coordinate through 20 named Windows synchronization objects:
Protect concurrent access to shared data:
| Mutex | Purpose |
|---|---|
| 0 | Current frame index update |
| 1 | Source thread frame posting wait |
| 2 | Channel check/increment |
| 3, 4, 5 | Next-write index for feeds 0, 1, 2 |
| 6, 7, 8 | Motion detection signal for feeds 0, 1, 2 |
| 9 | Output feed and frame count |
| 10 | Frames-this-channel counter |
| 11 | Motion info: min type2 frame |
| 12 | Motion info: movie start |
| 13 | Motion info: movie end |
| 14 | Frame builder broadcast |
| 15 | Index of last frame built |
| 16, 17 | Viewer shared memory access |
All frame data is stored as YUV420 planar:
This format halves the data compared to YUV422 and is native to H.264 encoding.
Each feed channel has a 520-frame circular buffer (~8.7 seconds at 60fps). The next_write index advances modulo 520. Readers track their own position and must stay within the buffer window or they'll read stale data.
Output frames combine two camera feeds vertically:
| Display Type | Top 540 lines | Bottom 540 lines | When Used |
|---|---|---|---|
| Type 0/1 | Feed 1 (middle) | Feed 0 (top of hill) | Jumper in top/middle of hill |
| Type 2 | Feed 1 (middle) | Feed 2 (bottom of hill) | Jumper past top of hill |