mirror of
https://github.com/scottlamb/moonfire-nvr.git
synced 2024-12-26 23:25:55 -05:00
fix panic when requesting zero segment duration
The recording::Segment was constructing a segment with no frames in it, which was causing a panic when appending a zero-length stts to the Slices. Fix this in a couple ways: * Slices::append should return Err rather than panic. No reason to crash the whole program when we have trouble serving a single .mp4 request. * recording::Segment shouldn't produce zero-frame segments
This commit is contained in:
parent
1d08698d0c
commit
9041eeb907
@ -1405,8 +1405,7 @@ impl BodyState {
|
||||
|
||||
fn append_slice(&mut self, len: u64, t: SliceType, p: usize) -> Result<(), Error> {
|
||||
let l = self.slices.len();
|
||||
self.slices.append(Slice::new(l + len, t, p)?);
|
||||
Ok(())
|
||||
self.slices.append(Slice::new(l + len, t, p)?)
|
||||
}
|
||||
|
||||
/// Appends a static bytestring, flushing the buffer if necessary.
|
||||
|
@ -406,10 +406,13 @@ impl Segment {
|
||||
if self_.desired_range_90k.start == 0 &&
|
||||
self_.desired_range_90k.end == recording.duration_90k {
|
||||
// Fast path. Existing entry is fine.
|
||||
trace!("recording::Segment::new fast path, recording={:#?}", recording);
|
||||
return Ok(self_)
|
||||
}
|
||||
|
||||
// Slow path. Need to iterate through the index.
|
||||
trace!("recording::Segment::new slow path, desired_range_90k={:?}, recording={:#?}",
|
||||
self_.desired_range_90k, recording);
|
||||
db.with_recording_playback(self_.camera_id, self_.recording_id, |playback| {
|
||||
let mut begin = Box::new(SampleIndexIterator::new());
|
||||
let data = &(&playback).video_index;
|
||||
@ -441,7 +444,7 @@ impl Segment {
|
||||
self_.frames = 0;
|
||||
self_.key_frames = 0;
|
||||
}
|
||||
if it.start_90k >= end_90k {
|
||||
if it.start_90k >= end_90k && self_.frames > 0 {
|
||||
break;
|
||||
}
|
||||
self_.frames += 1;
|
||||
@ -709,6 +712,18 @@ mod tests {
|
||||
assert_eq!(&get_frames(&db.db, &segment, |it| it.bytes), &[2, 3]);
|
||||
}
|
||||
|
||||
/// Even if the desired duration is 0, there should still be a frame.
|
||||
#[test]
|
||||
fn test_segment_zero_desired_duration() {
|
||||
testutil::init();
|
||||
let mut encoder = SampleIndexEncoder::new();
|
||||
encoder.add_sample(1, 1, true);
|
||||
let db = TestDb::new();
|
||||
let row = db.create_recording_from_encoder(encoder);
|
||||
let segment = Segment::new(&db.db.lock(), &row, 0 .. 0).unwrap();
|
||||
assert_eq!(&get_frames(&db.db, &segment, |it| it.bytes), &[1]);
|
||||
}
|
||||
|
||||
/// Test a `Segment` which uses the whole recording.
|
||||
/// This takes a fast path which skips scanning the index in `new()`.
|
||||
#[test]
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
//! Tools for implementing a `http_entity::Entity` body composed from many "slices".
|
||||
|
||||
use error::Error;
|
||||
use reffers::ARefs;
|
||||
use futures::stream;
|
||||
use futures::Stream;
|
||||
@ -92,12 +93,16 @@ impl<S> Slices<S> where S: Slice {
|
||||
self.slices.reserve(additional)
|
||||
}
|
||||
|
||||
/// Appends the given slice.
|
||||
pub fn append(&mut self, slice: S) {
|
||||
assert!(slice.end() > self.len, "end {} <= len {} while adding slice {:?} to slices:\n{:?}",
|
||||
slice.end(), self.len, slice, self);
|
||||
/// Appends the given slice, which must have end > the Slice's current len.
|
||||
pub fn append(&mut self, slice: S) -> Result<(), Error> {
|
||||
if slice.end() <= self.len {
|
||||
return Err(Error::new(
|
||||
format!("end {} <= len {} while adding slice {:?} to slices:\n{:?}",
|
||||
slice.end(), self.len, slice, self)));
|
||||
}
|
||||
self.len = slice.end();
|
||||
self.slices.push(slice);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns the total byte length of all slices.
|
||||
@ -182,11 +187,11 @@ mod tests {
|
||||
lazy_static! {
|
||||
static ref SLICES: Slices<FakeSlice> = {
|
||||
let mut s = Slices::new();
|
||||
s.append(FakeSlice{end: 5, name: "a"});
|
||||
s.append(FakeSlice{end: 5+13, name: "b"});
|
||||
s.append(FakeSlice{end: 5+13+7, name: "c"});
|
||||
s.append(FakeSlice{end: 5+13+7+17, name: "d"});
|
||||
s.append(FakeSlice{end: 5+13+7+17+19, name: "e"});
|
||||
s.append(FakeSlice{end: 5, name: "a"}).unwrap();
|
||||
s.append(FakeSlice{end: 5+13, name: "b"}).unwrap();
|
||||
s.append(FakeSlice{end: 5+13+7, name: "c"}).unwrap();
|
||||
s.append(FakeSlice{end: 5+13+7+17, name: "d"}).unwrap();
|
||||
s.append(FakeSlice{end: 5+13+7+17+19, name: "e"}).unwrap();
|
||||
s
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user