mirror of
https://github.com/scottlamb/moonfire-nvr.git
synced 2025-12-08 08:42:41 -05:00
Rust rewrite
I should have submitted/pushed more incrementally but just played with it on
my computer as I was learning the language. The new Rust version more or less
matches the functionality of the current C++ version, although there are many
caveats listed below.
Upgrade notes: when moving from the C++ version, I recommend dropping and
recreating the "recording_cover" index in SQLite3 to pick up the addition of
the "video_sync_samples" column:
$ sudo systemctl stop moonfire-nvr
$ sudo -u moonfire-nvr sqlite3 /var/lib/moonfire-nvr/db/db
sqlite> drop index recording_cover;
sqlite3> create index ...rest of command as in schema.sql...;
sqlite3> ^D
Some known visible differences from the C++ version:
* .mp4 generation queries SQLite3 differently. Before it would just get all
video indexes in a single query. Now it leads with a query that should be
satisfiable by the covering index (assuming the index has been recreated as
noted above), then queries individual recording's indexes as needed to fill
a LRU cache. I believe this is roughly similar speed for the initial hit
(which generates the moov part of the file) and significantly faster when
seeking. I would have done it a while ago with the C++ version but didn't
want to track down a lru cache library. It was easier to find with Rust.
* On startup, the Rust version cleans up old reserved files. This is as in the
design; the C++ version was just missing this code.
* The .html recording list output is a little different. It's in ascending
order, with the most current segment shorten than an hour rather than the
oldest. This is less ergonomic, but it was easy. I could fix it or just wait
to obsolete it with some fancier JavaScript UI.
* commandline argument parsing and logging have changed formats due to
different underlying libraries.
* The JSON output isn't quite right (matching the spec / C++ implementation)
yet.
Additional caveats:
* I haven't done any proof-reading of prep.sh + install instructions.
* There's a lot of code quality work to do: adding (back) comments and test
coverage, developing a good Rust style.
* The ffmpeg foreign function interface is particularly sketchy. I'd
eventually like to switch to something based on autogenerated bindings.
I'd also like to use pure Rust code where practical, but once I do on-NVR
motion detection I'll need to existing C/C++ libraries for speed (H.264
decoding + OpenCL-based analysis).
This commit is contained in:
117
README.md
117
README.md
@@ -60,59 +60,51 @@ edge version from the command line via git:
|
||||
# Building from source
|
||||
|
||||
There are no binary packages of Moonfire NVR available yet, so it must be built
|
||||
from source. It requires several packages to build:
|
||||
from source.
|
||||
|
||||
* [CMake](https://cmake.org/) version 3.1.0 or higher.
|
||||
* a C++11 compiler, such as [gcc](https://gcc.gnu.org/) 4.7 or higher.
|
||||
* [ffmpeg](http://ffmpeg.org/), including `libavutil`,
|
||||
The `rust` branch contains a rewrite into the [Rust Programming
|
||||
Language](https://www.rust-lang.org/en-US/). In the long term, I expect this
|
||||
will result in a more secure, full-featured, easy-to-install software. In the
|
||||
short term, there will be growing pains. Rust is a new programming language.
|
||||
Moonfire NVR's primary author is new to Rust. And Moonfire NVR is a young
|
||||
project.
|
||||
|
||||
You will need the following C libraries installed:
|
||||
|
||||
* [ffmpeg](http://ffmpeg.org/) version 2.x, including `libavutil`,
|
||||
`libavcodec` (to inspect H.264 frames), and `libavformat` (to connect to RTSP
|
||||
servers and write `.mp4` files). Note ffmpeg versions older than 55.1.101,
|
||||
along with all versions of the competing project [libav](http://libav.org),
|
||||
does not support socket timeouts for RTSP. For reliable reconnections on
|
||||
error, it's strongly recommended to use ffmpeg >= 55.1.101.
|
||||
* [libevent](http://libevent.org/) 2.1, for the built-in HTTP server.
|
||||
(This might be replaced with the more full-featured
|
||||
[nghttp2](https://github.com/tatsuhiro-t/nghttp2) in the future.)
|
||||
Unfortunately, the libevent 2.0 bundled with current Debian releases is
|
||||
unsuitable.
|
||||
* [gflags](http://gflags.github.io/gflags/), for command line flag parsing.
|
||||
* [glog](https://github.com/google/glog), for debug logging.
|
||||
* [gperftools](https://github.com/gperftools/gperftools), for debugging.
|
||||
* [googletest](https://github.com/google/googletest), for automated testing.
|
||||
This will be automatically downloaded during the build process, so it's
|
||||
not necessary to install it beforehand.
|
||||
* [re2](https://github.com/google/re2), for parsing with regular expressions.
|
||||
* libuuid from [util-linux](https://en.wikipedia.org/wiki/Util-linux).
|
||||
servers and write `.mp4` files).
|
||||
|
||||
Note ffmpeg 3.x isn't supported yet by the Rust `ffmpeg` crate; see
|
||||
[rust-ffmpeg/issues/64](https://github.com/meh/rust-ffmpeg/issues/64).
|
||||
|
||||
Additionally, ffmpeg library versions older than 55.1.101, along with
|
||||
55.1.101, along with all versions of the competing project
|
||||
[libav](http://libav.org), don't not support socket timeouts for RTSP. For
|
||||
reliable reconnections on error, it's strongly recommended to use ffmpeg
|
||||
library versions >= 55.1.101.
|
||||
|
||||
* [SQLite3](https://www.sqlite.org/).
|
||||
|
||||
On Ubuntu 15.10 or Raspbian Jessie, the following command will install most
|
||||
pre-requisites (see also the `Build-Depends` field in `debian/control`):
|
||||
On Ubuntu 16.04.1 LTS or Raspbian Jessie, the following command will install
|
||||
all non-Rust dependencies:
|
||||
|
||||
$ sudo apt-get install \
|
||||
build-essential \
|
||||
cmake \
|
||||
libavcodec-dev \
|
||||
libavformat-dev \
|
||||
libavutil-dev \
|
||||
libgflags-dev \
|
||||
libgoogle-glog-dev \
|
||||
libgoogle-perftools-dev \
|
||||
libjsoncpp-dev \
|
||||
libre2-dev \
|
||||
sqlite3 \
|
||||
libsqlite3-dev \
|
||||
pkgconf \
|
||||
uuid-runtime \
|
||||
uuid-dev
|
||||
|
||||
libevent 2.1 will have to be installed from source. In the future, this
|
||||
dependency may be replaced or support may be added for automatically building
|
||||
libevent in-tree to avoid the inconvenience.
|
||||
uuid-runtime
|
||||
|
||||
uuid-runtime is only necessary if you wish to use the uuid command to generate
|
||||
uuids for your cameras (see below). If you obtain them elsewhere, you can skip this
|
||||
package.
|
||||
|
||||
Next, you need a nightly version of Rust and Cargo. The easiest way to install
|
||||
them is by following the instructions at [rustup.rs](https://www.rustup.rs/).
|
||||
|
||||
You can continue to follow the build/install instructions below for a manual
|
||||
build and install, or alternatively you can run the prep script called `prep.sh`.
|
||||
|
||||
@@ -121,11 +113,7 @@ build and install, or alternatively you can run the prep script called `prep.sh`
|
||||
|
||||
The script will take the following command line options, should you need them:
|
||||
|
||||
* `-E`: Forcibly purge all existing libevent packages. You would only do this
|
||||
if there is some apparent conflict (see remarks about building libevent
|
||||
from source).
|
||||
* `-f`: Force a build even if the binary appears to be installed. This can be useful
|
||||
on repeat builds.
|
||||
* `-D`: Skip database initialization.
|
||||
* `-S`: Skip updating and installing dependencies through apt-get. This too can be
|
||||
useful on repeated builds.
|
||||
|
||||
@@ -148,17 +136,9 @@ For instructions, you can skip to "[Camera configuration and hard disk mounting]
|
||||
|
||||
Once prerequisites are installed, Moonfire NVR can be built as follows:
|
||||
|
||||
$ mkdir release
|
||||
$ cd release
|
||||
$ cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||
$ make
|
||||
$ sudo make install
|
||||
|
||||
Alternatively, if you do have a sufficiently new apt-installed libevent
|
||||
installed, you may be able to prepare a `.deb` package:
|
||||
|
||||
$ sudo apt-get install devscripts dh-systemd
|
||||
$ debuild -us -uc
|
||||
$ RUST_TEST_THREADS=1 cargo test
|
||||
$ cargo build --release
|
||||
$ sudo install -m 755 target/release/moonfire-nvr /usr/local/bin
|
||||
|
||||
# Further configuration
|
||||
|
||||
@@ -279,9 +259,10 @@ been done for you. If not, Create
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/local/bin/moonfire-nvr \
|
||||
--sample_file_dir=/var/lib/moonfire-nvr/sample \
|
||||
--db_dir=/var/lib/moonfire-nvr/db \
|
||||
--http_port=8080
|
||||
--sample-file-dir=/var/lib/moonfire-nvr/sample \
|
||||
--db-dir=/var/lib/moonfire-nvr/db \
|
||||
--http-addr=0.0.0.0:8080
|
||||
Environment=RUST_LOG=info
|
||||
Type=simple
|
||||
User=moonfire-nvr
|
||||
Nice=-20
|
||||
@@ -310,10 +291,16 @@ and `systemctl` may be of particular interest.
|
||||
|
||||
# Troubleshooting
|
||||
|
||||
While Moonfire NVR is running, logs will be written to `/tmp/moonfire-nvr.INFO`.
|
||||
Also available will be `/tmp/moonfire-nvr.WARNING` and `/tmp/moonfire-nvr.ERROR`.
|
||||
These latter to contain only warning or more serious messages, respectively only
|
||||
error messages.
|
||||
While Moonfire NVR is running, logs will be written to stdout. The `RUST_LOG`
|
||||
environmental variable controls the log level; `RUST_LOG=info` is recommended.
|
||||
If running through systemd, try `sudo journalctl --unit moonfire-nvr` to view
|
||||
the logs.
|
||||
|
||||
If Moonfire NVR crashes with a `SIGSEGV`, the problem is likely an
|
||||
incompatible version of the C `ffmpeg` libraries; use the latest 2.x release
|
||||
instead. This is one of the Rust growing pains mentioned above. While most
|
||||
code written in Rust is "safe", the foreign function interface is not only
|
||||
unsafe but currently error-prone.
|
||||
|
||||
# <a name="help"></a> Getting help and getting involved
|
||||
|
||||
@@ -322,17 +309,11 @@ Please email the
|
||||
mailing list with questions, bug reports, feature requests, or just to say
|
||||
you love/hate the software and why.
|
||||
|
||||
I'd welcome help with testing, development (in C++, JavaScript, and HTML), user
|
||||
interface/graphic design, and documentation. Please email the mailing list
|
||||
if interested. Patches are welcome, but I encourage you to discuss large
|
||||
I'd welcome help with testing, development (in Rust, JavaScript, and HTML),
|
||||
user interface/graphic design, and documentation. Please email the mailing
|
||||
list if interested. Patches are welcome, but I encourage you to discuss large
|
||||
changes on the mailing list first to save effort.
|
||||
|
||||
C++ code should be written using C++11 features, should follow the [Google C++
|
||||
style guide](https://google.github.io/styleguide/cppguide.html) for
|
||||
consistency, and should be automatically tested where practical. But don't
|
||||
worry about this too much; I'm much happier to work with you to refine a rough
|
||||
draft patch than never see your contribution at all!
|
||||
|
||||
# License
|
||||
|
||||
This file is part of Moonfire NVR, a security camera digital video recorder.
|
||||
|
||||
Reference in New Issue
Block a user