upgrade to Retina v0.3.9

This alone improves interop and diagnostics, as noted in Retina's
release notes. We also now give the camera name to the session group
(for improved logging of TEARDOWN operations) and expose the RTSP
server's "tool" attribute in debug logs and the config UI's "Test"
button.

Fixes #209
Fixes #213
This commit is contained in:
Scott Lamb 2022-04-12 14:57:16 -07:00
parent 3bc410b417
commit 5e7d558f99
7 changed files with 32 additions and 8 deletions

View File

@ -6,6 +6,10 @@ changes, see Git history.
Each release is tagged in Git and on the Docker repository
[`scottlamb/moonfire-nvr`](https://hub.docker.com/r/scottlamb/moonfire-nvr).
## unreleased
* upgrade to Retina 0.3.9, improving camera interop and diagnostics
## `v0.7.3` (2022-03-22)
* security fix: check the `Origin` header on live stream WebSocket requests

4
server/Cargo.lock generated
View File

@ -1640,9 +1640,9 @@ dependencies = [
[[package]]
name = "retina"
version = "0.3.8"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3629d5f6a30d1a0ee184bd2a3e62eba8ffbb121250a8c72ed984575c9ffb0601"
checksum = "df90aca400866f8b1327902f7c9e93ab17f195c36b7e06b804e8acd3a79bbe41"
dependencies = [
"base64",
"bitreader",

View File

@ -46,7 +46,7 @@ parking_lot = "0.12.0"
password-hash = "0.3.2"
protobuf = "3.0.0-alpha.1"
reffers = "0.7.0"
retina = "0.3.7"
retina = "0.3.9"
ring = "0.16.2"
rusqlite = "0.27.0"
serde = { version = "1.0", features = ["derive"] }

View File

@ -214,7 +214,7 @@ fn press_test_inner(
.enable_io()
.build()?;
let _guard = rt.enter();
let (extra_data, _stream) = stream::OPENER.open(
let (extra_data, stream) = stream::OPENER.open(
&rt,
"test stream".to_owned(),
url,
@ -227,8 +227,10 @@ fn press_test_inner(
.transport(transport),
)?;
Ok(format!(
"{}x{} video stream",
extra_data.width, extra_data.height
"{}x{} video stream served by tool {:?}",
extra_data.width,
extra_data.height,
stream.tool(),
))
}

View File

@ -13,6 +13,7 @@ use fnv::FnvHashMap;
use hyper::service::{make_service_fn, service_fn};
use log::error;
use log::{info, warn};
use retina::client::SessionGroup;
use std::net::SocketAddr;
use std::path::Path;
use std::path::PathBuf;
@ -324,7 +325,9 @@ async fn inner(
let syncer = syncers.get(&sample_file_dir_id).unwrap();
let session_group = session_groups_by_camera
.entry(camera.id)
.or_default()
.or_insert_with(|| {
Arc::new(SessionGroup::default().named(camera.short_name.clone()))
})
.clone();
let mut streamer = streamer::Streamer::new(
&env,

View File

@ -45,6 +45,7 @@ pub struct VideoFrame {
}
pub trait Stream: Send {
fn tool(&self) -> Option<&retina::client::Tool>;
fn next(&mut self) -> Result<VideoFrame, Error>;
}
@ -63,7 +64,7 @@ impl Opener for RealOpener {
let options = options.user_agent(format!("Moonfire NVR {}", env!("CARGO_PKG_VERSION")));
let (session, video_params, first_frame) = rt.block_on(tokio::time::timeout(
RETINA_TIMEOUT,
RetinaStream::play(url, options),
RetinaStream::play(&label, url, options),
))??;
let extra_data = h264::parse_extra_data(video_params.extra_data())?;
let stream = Box::new(RetinaStream {
@ -91,6 +92,7 @@ struct RetinaStream<'a> {
impl<'a> RetinaStream<'a> {
/// Plays to first frame. No timeout; that's the caller's responsibility.
async fn play(
label: &str,
url: Url,
options: retina::client::SessionOptions,
) -> Result<
@ -102,6 +104,7 @@ impl<'a> RetinaStream<'a> {
Error,
> {
let mut session = retina::client::Session::describe(url, options).await?;
log::debug!("connected to {:?}, tool {:?}", label, session.tool());
let (video_i, mut video_params) = session
.streams()
.iter()
@ -177,6 +180,10 @@ impl<'a> RetinaStream<'a> {
}
impl<'a> Stream for RetinaStream<'a> {
fn tool(&self) -> Option<&retina::client::Tool> {
Pin::into_inner(self.session.as_ref()).tool()
}
fn next(&mut self) -> Result<VideoFrame, Error> {
let frame = self.first_frame.take().map(Ok).unwrap_or_else(|| {
self.rt
@ -247,6 +254,10 @@ pub mod testutil {
}
impl Stream for Mp4Stream {
fn tool(&self) -> Option<&retina::client::Tool> {
None
}
fn next(&mut self) -> Result<VideoFrame, Error> {
let sample = self
.reader

View File

@ -313,6 +313,10 @@ mod tests {
}
impl Stream for ProxyingStream {
fn tool(&self) -> Option<&retina::client::Tool> {
self.inner.tool()
}
fn next(&mut self) -> Result<stream::VideoFrame, Error> {
if self.pkts_left == 0 {
bail!("end of stream");