Commit Graph

176 Commits

Author SHA1 Message Date
Scott Lamb
144a640339 allow overriding tokio worker threads
I see a lot of yields and such in CPU profiles. I think the workers
are frequently waking up, finding there's not much to do, and going back
to sleep. Reducing the number of worker threads seems reasonable.
2021-06-28 15:00:12 -07:00
Scott Lamb
547c106e6b tell retina not to enforce timestamps
Moonfire NVR has some enforcement on its own; this makes retina vs
ffmpeg more of an apples-to-apples comparison.

I'm also thinking of dropping enforcement from retina; enough things
have sketchy timestamps that this policy doesn't make much sense anyway.
2021-06-28 14:26:36 -07:00
Scott Lamb
4c95df5ba7 upgrade to retina 0.0.3
The new version is more efficient.
2021-06-28 14:25:35 -07:00
Scott Lamb
9cb19d5c82 tweak deps, eliminating strsim 0.8 dependency
I also enabled the colored help option for clap, since we're paying for
the color dep anyway.
2021-06-15 00:45:11 -07:00
Scott Lamb
92a365eb73 use released versions of a few deps 2021-06-09 14:36:14 -07:00
Scott Lamb
032bd76577 support --rtsp-library=retina (#37)
This isn't well-tested and doesn't yet support an initial connection
timeout. But in a quick test, it successfully returns video!

I'd like to do some more aggressive code restructuring for zero-copy
and to have only one writer thread per sample file directory (rather
than the syncer thread + one writer thread per RTSP stream). But I'll
likely wait until I drop support for ffmpeg entirely.
2021-06-07 14:40:26 -07:00
Scott Lamb
7699696bd9 remove half-baked analytics module
This is (slightly) complicating the switch from ffmpeg to retina
as the RTSP client. And it's not really that close to what I want
to end up with for analytics:

*   I'd prefer the analytics happen in a separate process for
    several reasons
*   Feeding the entire frame to the object detector doesn't produce
    good results.
*   It doesn't do anything with the results yet anyway.
2021-06-06 21:14:42 -07:00
Scott Lamb
9cc63faf29 logging improvements
*   allow debug/trace logging on release builds again
*   enable log messages from hyper. I didn't notice they went
    away with 0.14.0, although there's a breaking change in the log:
    https://github.com/hyperium/hyper/blob/master/CHANGELOG.md#v0140-2020-12-23
*   downgrade some particularly spammy messages
2021-06-04 23:33:51 -07:00
Scott Lamb
7591146928 fix thinko in video sample chunk code
This caused served chunks to be truncated. On seek, nginx sometimes
served 502 errors, chrome sometimes returned
ERR_CONTENT_LENGTH_MISMATCH, and videos weren't playing properly.
2021-06-04 23:10:13 -07:00
Scott Lamb
bb69d1488e cargo fmt 2021-06-04 20:25:19 -07:00
Scott Lamb
23d77693de read sample files from dedicated threads
Reading from the mmap()ed region in the tokio threads could cause
them to stall:

*   That could affect UI serving when there were concurrent
    UI requests (i.e., not just requests that needed the reads in
    question anyway).
*   If there's a faulty disk, it could cause the UI to totally hang.
    Better to not mix disks between threads.
*   Soon, I want to handle RTSP from the tokio threads (#37). Similarly,
    we don't want RTSP streaming to block on operations from unrelated
    disks.

I went with just one thread per disk which I think is sufficient.
But it'd be possible to do a fixed-size pool instead which might improve
latency when some pages are already cached.

I also dropped the memmap dependency. I had to compute the page
alignment anyway to get mremap to work, and Moonfire NVR already is
Unix-specific, so there wasn't much value from the memmap or memmap2
crates.

Fixes #88
2021-06-04 19:50:13 -07:00
Scott Lamb
0068a9ae70 more anamorphic streams
* my dad's GW4089IP cameras use 720x480
* some Reolink cameras use 640x352
* I'm playing with rotated cameras (16x9 -> 9x16)

I'd prefer to calculate pasp from a configured camera aspect ratio
than to hardcode the assumption these are 16x9, but that requires
a schema change. This is an improvement for now.
2021-05-22 20:45:07 -07:00
Scott Lamb
54bd068706 address some no-op clippy warnings 2021-05-17 15:00:51 -07:00
Scott Lamb
603f02b686 stop using old tempdir crate 2021-05-17 13:08:18 -07:00
Scott Lamb
13b497e243 update libpasta deps 2021-05-17 13:02:26 -07:00
Scott Lamb
8b37c77558 de-dupe prettydiff deps via a fork 2021-05-17 12:17:18 -07:00
Scott Lamb
ef0bc8acf9 update various other deps 2021-05-17 11:05:54 -07:00
Scott Lamb
f922afaa26 update rusqlite
The big difference here is query_named and execute_named have gone
away. Fair number of lines changes but straightforward.
2021-05-17 10:50:48 -07:00
Scott Lamb
dc1c9afa73 cargo update
The immediate motivation is to address these CI failures with nightly:
https://github.com/scottlamb/moonfire-nvr/runs/2593322801?check_suite_focus=true
```
   Compiling lock_api v0.4.2
error[E0557]: feature has been removed
  --> /home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/lock_api-0.4.2/src/lib.rs:91:42
   |
91 | #![cfg_attr(feature = "nightly", feature(const_fn))]
   |                                          ^^^^^^^^ feature has been removed
   |
   = note: split into finer-grained feature gates
```

Strangely, they don't occur locally with "rustc 1.54.0-nightly
(fe72845f7 2021-05-16)" but do on CI with the exact same version?!?
I don't get it, but lock-api 0.4.4 is advertised as being updated for
latest nightly, so I expect this will address the problem anyway.
2021-05-17 10:31:06 -07:00
Scott Lamb
80ec7ab1d0 cleanup some awkward Option call chains 2021-05-17 09:34:10 -07:00
Scott Lamb
a1e78ea48b better debugging when unable to insert VSE
I saw this error once:

Apr 27 21:01:33 nuc moonfire-nvr[188570]: s-reolink-sub
moonfire_nvr::streamer] reolink-sub: sleeping for Duration { secs: 1,
nanos: 0 } after error: CHECK constraint failed: video_sample_entry

and would like to understand it better.
2021-04-27 22:52:47 -07:00
Scott Lamb
c53250c0c5 support negating Durations 2021-04-22 10:04:22 -07:00
Scott Lamb
d99cab5f27 std::time::Duration -> base::Duration conversion 2021-04-22 09:56:01 -07:00
Scott Lamb
1e314e09d0 refine timestamps in json signals api
*   API change: in update signals, allow setting a start time relative
    to now. This is an accuracy improvement in the case where the client
    has been retrying an initial request for a while. Kind of an obscure
    corner case but easy enough to address. And use a more convenient
    enum representation.

*   in update signals, choose `now` before acquiring the database lock.
    If lock acquisition takes a long time, this more accurately reflects
    the time the caller intended.

*   in general, make Time and Duration (de)serializable and use them
    in json types. This makes the types more self-describing, with
    better debug printing on both the server side and on the client
    library (in moonfire-playground). To make this work, base has to
    import serde which initially seemed like poor layering to me, but
    serde seems to be imported in some pretty foundational Rust crates
    for this reason. I'll go with it.
2021-04-21 21:06:15 -07:00
Scott Lamb
4ffb922805 fix request of death in /api/signals 2021-04-12 21:57:16 -07:00
Scott Lamb
2936c138c5 various doc improvements
I bumped the minimum Rust version because I'm taking advantage of
the rustdoc linking added in Rust 1.48:
https://blog.rust-lang.org/2020/11/19/Rust-1.48.html#easier-linking-in-rustdoc
2021-04-10 17:34:52 -07:00
Scott Lamb
7c0a634bed avoid clock problems on some Docker setups
In particular, this was happening out of the box on Raspberry Pi OS Lite
20210304, as reported by ironoxidizer@gmail.com here:
https://groups.google.com/g/moonfire-nvr-users/c/2j9LvfFl2u8/m/tJcNS2WfCQAJ

*   adjust main.rs to make the problem more obvious
*   mention it in the troubleshooting guide
*   sidestep it in the nvr docker wrapper script

also just use --networking=host rather than --publish (avoiding a proxy
process). I'm using Docker to simplify the build and deployment process,
not as a security boundary, so just do the simpler thing.
2021-04-08 22:21:03 -07:00
Scott Lamb
0c34ea8314 optionally skip installing panic hook
For debugging this failure:
https://groups.google.com/g/moonfire-nvr-users/c/2j9LvfFl2u8/m/bWpwFilTCQAJ
2021-04-07 22:54:02 -07:00
Scott Lamb
f8d5610e3e add links directly from code to standards page 2021-04-01 16:11:33 -07:00
Scott Lamb
8465b49cfa Prepare v0.6.3 release
...including changelog and new screenshots in the README.
2021-03-31 15:21:09 -07:00
Scott Lamb
560fe804d6 use SameSite=Lax instead of SameSite=Strict
To improve reliability of live streams (#59) on Safari.

Safari was dropping the cookie from websocket update requests.
(But it worked sometimes. I don't get why.) I saw folks on the Internet
thinking this related to HttpOnly:

*   https://developer.apple.com/forums/thread/104488
*   https://stackoverflow.com/q/47742807/23584

but I still see this behavior without HttpOnly. SameSite=Strict vs
SameSite=Lax appears to make a difference. Try that instead.
SameSite=Strict is pointless for us anyway as noted in a new comment.
Turning off HttpOnly would be more unfortunate security-wise.
2021-03-31 13:08:03 -07:00
Scott Lamb
478323ec62 write fragmented .mp4s that Safari likes
As required for live view (#59) to work on Safari.

Safari has some "interesting" expectations:
*   There must be a non-empty list of compatible brands. The major brand
    is not automatically included. (Looks like ISO/IEC 14496-12 doesn't
    spell out which is correct.)
*   The tfdt box must be before the trun boxes. Moonfire NVR was not
    compliant with ISO/IEC 14496-12:2015 section 8.8.12.1 before.
    Chrome and Firefox didn't care, but Safari does.
*   The mdat must be written with the small format. Safari is not
    implementing the spec properly.

I figured these out by painstakingly comparing Moonfire NVR's output
with gpac's, making it match almost byte-for-byte until it worked, then
backing out changes one at a time to check which were relevant. Ugh!
2021-03-30 16:07:29 -07:00
Scott Lamb
b0b650b6b9 Merge branch 'master' into new-ui 2021-03-26 19:29:22 -07:00
Scott Lamb
2f3e8a8f57 update lexical-core 0.7.4->0.7.5
I hope this will fix the failures on CI:
https://github.com/scottlamb/moonfire-nvr/runs/2199560446?check_suite_focus=true

Looks like this version was made to do so:
https://github.com/rust-lang/rust/issues/81654

The confusing part is that lexical-core 0.7.4 seems to compile fine
on my workstation with nightly-2021-03-25-x86_64-unknown-linux-gnu,
but not on CI with the same version?!? still, this will probably fix it.
2021-03-26 19:07:30 -07:00
Scott Lamb
2954a56fce send keepalives on live.m4s
Chrome appears to time out at 60 seconds of inactivity otherwise.
I think it's better to keep the stream open, even if the camera is
broken.

The implementation looks awkward, but that might be the state of Rust
async right now.
2021-03-25 23:11:08 -07:00
Scott Lamb
f9c46dca89 fix incorrect prev_media_duration_90k calculation
I spotted this by inspection: adding a media time and wall time didn't
look right. I also confirmed the brokenness on my primary NVR:

```
sqlite> .mode column
sqlite> select
   ...>   r1.composite_id,
   ...>   r1.prev_media_duration_90k,
   ...>   r1.wall_duration_90k,
   ...>   r1.media_duration_delta_90k,
   ...>   r2.composite_id,
   ...>   r2.prev_media_duration_90k
   ...> from
   ...>   recording r1 join recording r2 on (r1.composite_id = r2.composite_id - 1)
   ...> where
   ...>   r1.prev_media_duration_90k + r1.wall_duration_90k + r1.media_duration_delta_90k !=
   ...>     r2.prev_media_duration_90k
   ...> limit 5;
4296791095    2232623913716            5398956            154                       4296791096    2232629312672
4296791096    2232629312672            5400016            38                        4296791097    2232634712688
4296791097    2232634712688            5400729            105                       4296791098    2232640113417
4296791098    2232640113417            5399024            80                        4296791099    2232645512441
4296791099    2232645512441            5400770            124                       4296791100    2232650913211
```

In the first row, the second recording's prev_media_duration_90k is the
first's prev_media_duration_90k plus its wall time, not its media time.
2021-03-25 22:09:29 -07:00
Scott Lamb
6fd4f8975b build cleanly with nightly Rust 2021-03-14+
The CI nightly builds had been broken with the following error:

```
error: custom inner attributes are unstable
  --> /home/runner/work/moonfire-nvr/moonfire-nvr/server/target/debug/build/moonfire-db-415ce696a754c614/out/schema.rs:10:4
   |
10 | #![rustfmt::skip]
   |    ^^^^^^^^^^^^^
   |
   = note: `#[deny(soft_unstable)]` on by default
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #64266 <https://github.com/rust-lang/rust/issues/64266>
```

I'd thought this was by mistake given that #[rustfmt::skip] is still
advertised on rustfmt's github page, but maybe not. Looks like
rust-protobuf's newest version uses
`#![cfg_attr(rustfmt, rustfmt::skip)]` to avoid this error.

Also fix a warning on nightly about an extraneous semicolon.
2021-03-24 08:10:45 -07:00
Scott Lamb
abcd650304 present signal days in API requests
I also enforced some invariants in the signals code, fixing a couple
bugs. The signals code is more complex than I'd like, but hopefully
is working now.
2021-03-23 21:07:07 -07:00
Scott Lamb
caf65a045b use 90k units for signal days map
I'd once thought about using 1 second resolution for signals and wrote
this map to match that. But I decided to match signals to the timestamps
used elsewhere instead. Match that for the days map also.
2021-03-23 11:33:51 -07:00
Scott Lamb
7fb8cd7c6a day map datastructure for signals
Not yet actually used.
2021-03-23 10:58:07 -07:00
Scott Lamb
3ec60b85a3 extract & generalize calendar day indexes
My main goal is to support creating indexes for signals as well as
recordings. An additional goal is to just shrink db.rs a bit; it's
gotten quite large.
2021-03-23 09:40:52 -07:00
Scott Lamb
56661924ae Merge branch 'master' into new-ui 2021-03-12 14:53:15 -08:00
Scott Lamb
d5320302a3 prepare version 0.6.2 2021-03-12 12:36:20 -08:00
Scott Lamb
1458d668d7 tweak color env variable options
As noted in mylog's 2b1085c:
Looks like both the GNU tools' --color argument and cargo's
CARGO_TERM_COLOR expect always/never rather than on/off. Match that.
Might as well understand off/no/false and on/yes/true also.
2021-03-12 09:24:20 -08:00
Scott Lamb
ba10cc21cc use moonfire-ffmpeg that *really* builds with 1.45
(and moonfire-ffmpeg now has CI enabled to test this itself)
2021-03-11 20:10:18 -08:00
Scott Lamb
71ba9955c2 use moonfire-ffmpeg that builds with Rust 1.45
Fixes this CI failure:
https://github.com/scottlamb/moonfire-nvr/runs/2091884707
2021-03-11 19:21:17 -08:00
Scott Lamb
3c130f4fea update moonfire-ffmpeg
This picks up moonfire-ffmpeg's 4b13378:

support ffmpeg's multi-call log messages

This should fix this annoying log output:

```
W20210310 13:17:09.060 s-garage_west-main moonfire_ffmpeg::rtsp] 0xaf300950: RTP H.264 NAL unit type 29
W20210310 13:17:09.060 s-garage_west-main moonfire_ffmpeg::rtsp] 0xaf300950:  is not implemented. Update your FFmpeg version to the newest one from Git. If the problem still occurs, it means that your file has a feature which has not been implemented.
```

so it looks like this instead:

```
W20210310 13:17:09.060 s-garage_west-main moonfire_ffmpeg::rtsp] 0xaf300950: RTP H.264 NAL unit type 29 is not implemented. Update your FFmpeg version to the newest one from Git. If the problem still occurs, it means that your file has a feature which has not been implemented.
```
2021-03-11 19:04:44 -08:00
Scott Lamb
fd2d959daa update lock for 0.6.2-dev 2021-03-11 15:41:41 -08:00
Scott Lamb
10b2be3d54 changelog, including upcoming 0.6.2 2021-03-10 17:53:29 -08:00
Scott Lamb
984989dc1c small readability improvements to web.rs
I think this has a minor behavior change: permission denied replies
change to HTTP 403 where they were HTTP 401. The new behavior seems
more correct, as these errors can occur when authentication has
succeeded but the session in question is not authorized for the given
operation. The UI currently doesn't care about this distinction.
2021-03-10 16:21:34 -08:00
Scott Lamb
e66a88a591 fix invariant violation on pts jump (#112)
Looks like a refactoring in 9d7cdc09 introduced the possibility this
could fail (where before it might produce a silly i32 pts) and forgot
to restore the invariant.
2021-03-10 12:45:32 -08:00
Scott Lamb
9099d07dfa improve panic messages and docs (#112) 2021-03-10 08:12:49 -08:00
Scott Lamb
a845ba9769 send ffmpeg's logs through log crate (#112) 2021-03-09 22:09:30 -08:00
Scott Lamb
ea8bdef7d9 support color coding logs (#112)
ffmpeg was already doing this; now do it for native logs.
2021-03-09 22:09:30 -08:00
Scott Lamb
2808d5e139 help folks read logs (#112)
*   add more description to the troubleshooting guide
*   adjust the log format to match more recent glog
*   include a config for the lnav tool, which will help colorize,
    browse, and search the logs.

Next up: install an ffmpeg log callback for consistency.
2021-03-09 00:10:32 -08:00
Scott Lamb
2d45799b7d better error handling for authentication 2021-03-06 05:49:49 -08:00
Scott Lamb
cb4f30b5a2 rearrange check deletes to satisfy foreign key
Otherwise `moonfire-nvr check --delete-orphan-rows` can fail with this
error:

```
I0305 113848.655 main moonfire_db::check] Deleting 2 recording rows
E0305 113848.655 main moonfire_nvr] Exiting due to error: FOREIGN KEY constraint failed
```

The new order matches the online system's `db::raw::delete_recordings`.
2021-03-05 12:02:43 -08:00
Scott Lamb
9706dcaba1 Merge branch 'master' into new-ui 2021-02-22 13:48:20 -08:00
Scott Lamb
d7eea63829 minor api fixes
*   videoSampleEntryId should be a number, not a string
*   fix some markdown formatting
*   fix missing description of sampleFileBytes
2021-02-22 13:46:51 -08:00
Scott Lamb
f281922359 start a new React-based UI (#111)
This doesn't do much yet but should provide a better foundation for
improvement than the jQuery UI, as described in the github issue.
2021-02-17 19:42:32 -08:00
Scott Lamb
c547a49ac8 shorten per-file copyright headers
I'm tired of all the boilerplate, so use the new
GPL-3.0-linking-exception license identifier instead in all the server
components.

I left the ui stuff alone because I'm just going to replace it (#111).

Add a checker for the header because it's easy to forget.
2021-02-17 15:39:17 -08:00
Scott Lamb
97678f42e4 rustfmt everything
I want to make the project more accessible by not expecting folks to
match my idiosyncratic style. Now almost [1] everything is written
in the "standard" style. CI enforces this.

[1] "Almost": I used #[rustfmt::skip] in a few sections where I felt
aligning things in columns significantly improves readability.
2021-02-17 09:17:24 -08:00
Scott Lamb
64f8d38e01 0.6.1 2021-02-16 12:01:51 -08:00
Scott Lamb
ed521521a4 fix SQLite3 integrity check 2021-02-11 20:27:12 -08:00
Scott Lamb
fdb6603b5e also cleanup "Recording .. missing playback row" 2021-02-11 20:10:38 -08:00
Scott Lamb
7f711eedeb add some mutation flags to moonfire-nvr check
For recovering from corruption, as in #107. These should aid in
restoring database integrity without throwing away the entire database.
I only added the conditions that came up in #107, so far.

*   "Missing ... row" => --trash-orphan-sample-files
*   "Recording ... missing file" => --delete-orphan-rows
*   "bad video_index" => --trash-corrupt-rows
2021-02-11 20:03:28 -08:00
Scott Lamb
972f26f30a check SQLite database integrity 2021-02-11 15:24:24 -08:00
Scott Lamb
cdd878f452 compare schema version on "moonfire-nvr check" 2021-02-11 15:21:05 -08:00
Scott Lamb
51f43e9124 suppress some "moonfire-nvr check" false positives
In particular, if there are recordings in progress when the process
dies, they may still be around when check runs. They are easily
identifiable by having an id > cum_recordings and get automatically
deleted on startup, so there's no reason to complain about them.
2021-02-11 15:06:04 -08:00
Scott Lamb
8bfd96f9a3 fix missing newline in error msg 2021-02-11 11:07:16 -08:00
Scott Lamb
fb5b414297 fix missing newline in error msg 2021-02-11 11:06:13 -08:00
Scott Lamb
9a5957d5ef overhaul error messages
Inspired by the poor error message here:
https://github.com/scottlamb/moonfire-nvr/issues/107#issuecomment-777587727

*   print the friendlier Display version of the error rather than Debug.
    Eg, "EROFS: Read-only filesystem" rather than "Sys(EROFS)". Do this
    everywhere: on command exit, on syncer retries, and on stream
    retries.
*   print the most immediate problem and additional lines for each
    cause.
*   print the backtrace or an advertisement for RUST_BACKTRACE=1 if it's
    unavailable.
*   also mention RUST_BACKTRACE=1 in the troubleshooting guide.
*   add context in various places, including pathnames. There are surely
    many places more it'd be helpful, but this is a start.
*   allow subcommands to return failure without an Error.
    In particular, "moonfire-nvr check" does its own error printing
    because it wants to print all the errors it finds. Printing "see
    earlier errors" with a meaningless stack trace seems like it'd just
    confuse. But I also want to get rid of the misleading "Success" at
    the end and 0 return to the OS.
2021-02-11 10:57:09 -08:00
Scott Lamb
ff1615a0b4 address database upgrade slowness (#107)
* give a rule of thumb for update time in the documentation
* log the SQLite3 version, which can affect performance
* do the vacuum in non-WAL mode, to correctly set the page size and to
  avoid very slow behavior on older SQLite3 versions. Larger page sizes
  are generally faster (including subsequent vacuum operations).
  This won't help much for the first vacuum after this change, but it
  will help afterward.
* likewise, set the page size properly on "moonfire-nvr init".
2021-02-10 22:28:40 -08:00
Scott Lamb
4e67af9909 upgrade some other deps 2021-01-27 12:42:29 -08:00
Scott Lamb
b114493729 upgrade tokio, bytes, hyper, reqwest, http-serve
This was mostly straightforward. The most confusing part waas the Sync
bound change on body streams. I copied what hyper did and it seemed to
work. /shruggie
2021-01-27 11:47:52 -08:00
Scott Lamb
dd66c7b0dd restructure into "server" and "ui" subdirs
Besides being more clear about what belongs to which, this helps with
docker caching. The server and ui parts are only rebuilt when their
respective subdirectories change.

Extend this a bit further by making the webpack build not depend on
the target architecture. And adding cache dirs so parts of the server
and ui build process can be reused when layer-wide caching fails.
2021-01-22 22:01:17 -08:00