-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
use larger read buffers #5
Comments
Actually, that's a lot better than ffmpeg already. /shruggie With ffmpeg for a minute, there are ~8000 times per second the buffer filled.
Looking at actual CPU rates (by diffing
tl;dr version of investigating where that CPU is going: has more to do Moonfire NVR's current tokio and thread setup than with retina. flamegraph says tokio wastes a bit of CPU on There's also a fair bit of thread handoffs because currently I'm using retina in the tokio threads and handing off to a thread per stream every frame to write data. Eventually I'll have one writer thread per sample file directory (2 instead of 12 in this deployment) and only write once per GOP (every 1 or 2 seconds instead of every 1/10th to 1/30th of a second), which will reduce memory. |
* switch the config interface over to use Retina and make the test button honor rtsp_transport = udp. * adjust the threading model of the Retina streaming code. Before, it spawned a background future that read from the runtime and wrote to a channel. Other calls read from this channel. After, it does work directly from within the block_on calls (no channels). The immediate motivation was that the config interface didn't have another runtime handy. And passing in a current thread runtime deadlocked. I later learned this is a difference between Runtime::block_on and Handle::block_on. The former will drive IO and timers; the latter will not. But this is also more efficient to avoid so many thread hand-offs. Both the context switches and the extra spinning that tokio appears to do as mentioned here: scottlamb/retina#5 (comment) This may not be the final word on the threading model. Eventually I may not have per-stream writing threads at all. But I think it will be easier to look at this after getting rid of the separate `moonfire-nvr config` subcommand in favor of a web interface. * in tests, read `.mp4` files via the `mp4` crate rather than ffmpeg. The annoying part is that this doesn't parse edit lists; oh well. * simplify the `Opener` interface. Formerly, it'd take either a RTSP URL or a path to a `.mp4` file, and they'd share some code because they both sometimes used ffmpeg. Now, they're totally different libraries (`retina` vs `mp4`). Pull the latter out to a `testutil` module with a different interface that exposes more of the `mp4` stuff. Now `Opener` is just for RTSP. * simplify the h264 module. It had a lot of logic to deal with Annex B. Retina doesn't use this encoding. Fixes #36 Fixes #126
I was mildly surprised Moonfire NVR's CPU usage didn't go down noticeably when switching from ffmpeg to retina. There's not much CPU used in retina's code itself but I think it's making too many syscalls because it's using buffers that have too little available space. The histogram below counts reads that filled the buffer (and thus will require a follow-up syscall) bucketed by the available space in the buffer when the read started:
That's ~230 times per second the buffer filled (across 12 video streams); in most cases it was reading into a buffer with less than 1 KiB available.
I'm letting
tokio_util::codec::Framed
do the buffer management now, but I think I should do it myself instead. Or at least callreserve(4096)
before returning fromCodec::decode
(regardless of whether it was able to pull a full message).The text was updated successfully, but these errors were encountered: