75 lines
3.2 KiB
Markdown
75 lines
3.2 KiB
Markdown
|
|
# Real-time H.264 recording
|
|||
|
|
|
|||
|
|
The default recorder (`RawBgraRecorderSink`) writes uncompressed BGRA to disk
|
|||
|
|
and ships a `convert.cmd` for post-recording FFmpeg encoding. That's safe
|
|||
|
|
(no extra dependencies, works without an encoder installed) but disk-heavy:
|
|||
|
|
1080p60 = ~500 MB/s, 720p30 = ~88 MB/s.
|
|||
|
|
|
|||
|
|
For long shows or operators on slower disks, the engine ships a
|
|||
|
|
**`MediaFoundationRecorderSink`** that encodes to H.264 in real time using
|
|||
|
|
Windows Media Foundation. Inline encoding cuts disk pressure ~10× and
|
|||
|
|
produces a finished `.mp4` without the convert step.
|
|||
|
|
|
|||
|
|
It's behind a build flag because activating it requires adding a NuGet
|
|||
|
|
dependency. The structural code is already in
|
|||
|
|
`src/TeamsISO.Engine/Pipeline/MediaFoundationRecorderSink.cs`.
|
|||
|
|
|
|||
|
|
## Activating it
|
|||
|
|
|
|||
|
|
1. **Add the NuGet dependency** to the engine project:
|
|||
|
|
|
|||
|
|
dotnet add src/TeamsISO.Engine package Vortice.MediaFoundation --version 3.6.2
|
|||
|
|
|
|||
|
|
(Pin to a known-good version — Vortice's API surface is stable across
|
|||
|
|
3.6.x but the engine code targets the namespaces in 3.6.x. If a newer
|
|||
|
|
major version changes namespaces, the file may need adjustment.)
|
|||
|
|
|
|||
|
|
2. **Define the `MF_AVAILABLE` build symbol** in `TeamsISO.Engine.csproj`:
|
|||
|
|
|
|||
|
|
```xml
|
|||
|
|
<PropertyGroup>
|
|||
|
|
<DefineConstants>$(DefineConstants);MF_AVAILABLE</DefineConstants>
|
|||
|
|
</PropertyGroup>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
3. **Swap the recorder factory** in `IsoController.EnableIsoAsync`:
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// Old:
|
|||
|
|
recorder = new RawBgraRecorderSink(_loggerFactory.CreateLogger<RawBgraRecorderSink>());
|
|||
|
|
// New:
|
|||
|
|
recorder = new MediaFoundationRecorderSink(_loggerFactory.CreateLogger<MediaFoundationRecorderSink>());
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Both classes implement `IRecorderSink` so the rest of the pipeline is
|
|||
|
|
unchanged.
|
|||
|
|
|
|||
|
|
4. **Build and smoke-test.** Existing unit tests don't touch the recorder;
|
|||
|
|
the integration tier covers it once you've enabled MF.
|
|||
|
|
|
|||
|
|
## What the MF recorder produces
|
|||
|
|
|
|||
|
|
For each enabled ISO with recording on:
|
|||
|
|
- `<recordings>/<participant>/output.mp4` — H.264 video at the engine's
|
|||
|
|
configured resolution / framerate, target bitrate ~0.07 bits/pixel
|
|||
|
|
(~7 Mbps for 1080p30, ~3 Mbps for 720p30).
|
|||
|
|
- `<recordings>/<participant>/markers.txt` — tab-separated marker offsets
|
|||
|
|
from `IIsoController.AddRecordingMarker`. Manually chapter the .mp4 with
|
|||
|
|
`mp4chaps -c -i markers.txt output.mp4` (mp4chaps from the `mp4v2` tools).
|
|||
|
|
|
|||
|
|
## Trade-offs vs. RawBgraRecorderSink
|
|||
|
|
|
|||
|
|
| | Raw BGRA | Media Foundation H.264 |
|
|||
|
|
| --------------------- | --------------- | ---------------------- |
|
|||
|
|
| Dependencies | None | Vortice.MediaFoundation NuGet |
|
|||
|
|
| Disk @ 1080p60 | ~500 MB/s | ~50 MB/s |
|
|||
|
|
| Disk @ 720p30 | ~88 MB/s | ~9 MB/s |
|
|||
|
|
| CPU | Negligible | Moderate (inline encode) |
|
|||
|
|
| Output | `.bgra` + `convert.cmd` for FFmpeg post-pass | Finished `.mp4` |
|
|||
|
|
| Markers in container | No (sidecar JSON) | Sidecar `.txt`, chapter via mp4chaps |
|
|||
|
|
| Reliable on legacy GPUs | Yes | Yes (MF falls back to software encoder if no hw H.264) |
|
|||
|
|
|
|||
|
|
If your target machines have NVIDIA NVENC / Intel QuickSync, MF will use
|
|||
|
|
the hardware encoder transparently — that's the path that gives you
|
|||
|
|
multi-stream realtime H.264 with low CPU.
|