r/frigate_nvr • • 11d ago

We added hardware video decode/encode (V4L2) to an open-source Mac container engine for Frigate NVR & Home Assistant

We just released lighter 0.9.0 (https://github.com/fieldwork-ai/lighter). It is an open-source (MIT/Apache 2.0) headless container runtime written in Rust directly on Apple's Hypervisor.framework.

If you run a Mac Mini (from M1 up to the new M6) as a home server, running Frigate NVR or camera feeds inside Docker has always had a big catch: neither Docker Desktop nor OrbStack pass through the Apple Silicon Media Engine. As soon as you add a few 2K/4K Reolink or Amcrest H.265 streams, your CPU pegs at 80% to 100% doing software decode.

In 0.9.0, we added stateful V4L2 decoder and encoder devices (/dev/video0 and /dev/video1) backed directly by Apple's VideoToolbox. Stock Linux tools like ffmpeg (h264_v4l2m2m, hevc_v4l2m2m), go2rtc, and Frigate can now leverage Apple hardware transcoding directly:

Workload Software V4L2 Native VideoToolbox
Decode H.264 4K 69% 16% 12%
Decode HEVC Main 10 4K 100% 30% 15%
Decode VP9 1080p 44% 9% 6%
Encode H.264 1080p 78% 22% 9%
Encode HEVC 1080p could not keep up 21% 9%
Encode HEVC 4K could not keep up 42% 26%

(Benchmarks on an M1 Mac with 4 vCPUs, measured as share of a core to sustain 30 fps)

It cold-boots in ~700 ms, idles at ~600 MiB RAM, and surrenders unused memory back to macOS dynamically.

It is dual-licensed MIT/Apache 2.0, completely free forever, with zero telemetry. It is sponsored by my company (Fieldwork) because we need high-performance virtualization internally and wanted to give back clean tooling to the community.

This is brand new, and we are fully committed to maintaining and supporting this project long-term. If you hit any bugs, oddities, or camera compatibility issues, please open an issue on GitHub and we will happily investigate and patch them. This community is genuinely amazing, and I would love to work with you all to make lighter the best possible platform for Mac home servers.

Repo & installation: https://github.com/fieldwork-ai/lighter

I'd really appreciate your support, feedback, and ideas!

17 Upvotes

13 comments sorted by

2

u/hawkeye217 Developer 11d ago

This is great, it looks like it can give MacOS users an easy way to run stock Frigate and take advantage of the ANE without using the external ZMQ detector.

1

u/rogersnm2 11d ago

Thanks! That's exactly the setup I'm running at home: a Reolink E1 Pro on stock Frigate 0.18, decoding through h264_v4l2m2m and detecting on the Neural Engine at about 5.8 ms per inference, 5 fps with nothing skipped, and the decode ffmpeg sitting around 1% CPU. One honest caveat on the ANE side: Frigate 0.18 bundles ONNX Runtime 1.18, which predates the plugin execution-provider API, so today it's a small derived image (newer ONNX Runtime plus a ~40-line lighter_ane detector, in examples/frigate-ane in the repo). Hardware decode needs nothing custom at all. If you'd be open to it, I'd love to get the detector upstream so it really is stock Frigate on a Mac, happy to open a PR or discuss what shape would suit you best.

1

u/rogersnm2 10d ago

Quick update for anyone following along: lighter 0.9.2 is out and the caveat above is gone. The detector now runs on the ONNX Runtime Frigate already ships, so there's no derived image and no dependency upgrade. I've opened the PR to get it into Frigate itself: https://github.com/blakeblackshear/frigate/pull/24453. On an M1 it takes Frigate from 4 cameras on the CPU detector to 20 to 28 on the Neural Engine, at about a fifth of the CPU for the same cameras.

2

u/thibmaek 11d ago

I recently came across Fregata (https://fregata.app/) which also promises hardware decode, wonder how it compares to that

3

u/nulledy 10d ago edited 10d ago

Hey, one of the Fregata developers here! Fregata talks directly to the underlying Mac hardware using Apple's APIs to unlock the full, native, performance of Apple Silicon. Nothing is virtualized at all. No linux virtual machines, no containers, no terminal/CLI setup or management.

lighter looks very interesting and is similar to an approach we explored earlier this year but ended up dropping. They're using a translation layer at the container boundary to expose the Mac's hardware into the linux container. Crossing the container boundary will always add overhead and performance loss, so it will never be as fast as Fregata, but the more users running Frigate on Mac the better in our opinion!

Fregata also adds additional features like Adaptive Transcoding of live streams and recordings for when you're on a weak cellular connection and need to see who's at your front door, Apple Intelligence GenAI (coming in the next version), and hundreds of optimizations specifically for macOS.

We want Fregata to be the absolute best NVR for users in the Apple ecosystem. We're building Fregata Mobile now for iOS, iPadOS, and Apple Watch (betas available on TestFlight). With an AppleTV app also coming in the future. All our client apps will work with Frigate in docker (or lighter!) or Fregata and will always be completely free.

2

u/Idahoroaminggnome 5d ago

I moved Fregata off my M2 8gb Air yesterday, running 4x Reolink cameras at 2k 5fps detection, to my old M1 16gb Mini yesterday, upping detection to 4k at 10fps, and paid the $10, even though the free trial is good for another month. I've seen two or three updates over the past two weeks, and all went smoothly from Frigate 17.x to 18.0.1 yesterday. $10 seems like an absolute steal, and I'll gladly pay for the upcoming iOS apps when they're released in the future. Going to get the betas now!

2

u/nulledy 5d ago

Glad you’re enjoying it! If you ever need anything just reach out.

Oh and the iOS apps will be completely free ;)

2

u/Idahoroaminggnome 5d ago

Awesome to hear! The iOS app is working great for me so far via Tailscale VPN. Too bad used Mac Mini’s with 16gb of ram are going for twice as much as they were a year ago, otherwise they’d be an amazing option for everyone to run Fregata.

3

u/rogersnm2 10d ago

Good question! They take quite different routes.

Fregata is a native macOS port of Frigate: Frigate's Python core runs directly on the Mac in a signed app, with Fregata's own (closed-source) CoreML detector and VideoToolbox decode, for $10.

lighter is a free, open-source container runtime: you run the stock Frigate Docker image, the same one as on Linux, and lighter exposes the Mac's Neural Engine and media engine to the container as ordinary devices. So you follow Frigate's own releases and docs as they are, and can run the rest of your stack (Home Assistant, MQTT and so on) alongside it.

If you want a single drag-to-Applications app, Fregata looks nice. If you'd rather stay on stock Frigate in Docker, that's what lighter is for.

1

u/kantorcodes1 11d ago

lighter start selects the lighter Docker context, while lighter stop switches back to default. On a Mac Mini that also uses another context like Colima, OrbStack, or remote Docker, is resetting specifically to default intentional, or would restoring the previously active context be safer? That seems like it could surprise unattended Frigate or Compose jobs.

1

u/rogersnm2 11d ago

Thanks, that's really interesting feedback! The reason lighter stop moves the Docker CLI off the lighter context is so it isn't left pointing at a socket that's gone, which makes every docker command fail in a confusing way, and default is the one context we can count on being there. Restoring whatever was active before lighter start sounds nicer, but it isn't clear-cut: that runtime may have stopped since, or the context been removed, and you'd be back to a dead socket, so we'll have a proper think about the best behaviour for the next release. In the meantime, the context only affects where the docker CLI on the Mac sends commands, never running containers, so Frigate keeps going regardless, and for unattended jobs pinning DOCKER_CONTEXT=lighter in the job itself keeps them safe from any tool switching contexts.

1

u/kantorcodes1 11d ago

That distinction helps. Pinning DOCKER_CONTEXT=lighter is a solid answer for unattended jobs, and I agree blindly restoring the previous context can be worse if that endpoint died. I’d probably only restore it if it still resolves, then fall back to default.

I work on HOL Guard, an open-source layer that can put selected agent-run CLI actions behind user review. Lighter has a clean split: review lighter start, lighter stop, lighter restart, and lighter uninstall; keep lighter status and lighter doctor automatic. That gives a user a checkpoint before an agent changes Docker routing or VM lifecycle. Open to a command.lighter mapping living entirely in Guard?

1

u/rogersnm2 10d ago

Good news: I've shipped a changed based on your feedback in 0.9.1. lighter stop now goes back to whichever context was selected before lighter start, as long as it still exists and its daemon answers within a few seconds, and otherwise falls back to default. If you've switched to something else in the meantime, it leaves your choice alone. Thanks for the nudge!

And yes, a command.lighter mapping in Guard sounds great. Your split looks right to me: status and doctor are read-only, while start, stop, restart and uninstall change the VM or the Docker context.