Skip to content
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

Fix pause buffers #82

Merged
merged 20 commits into from
May 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
9dabb43
Address pausing of buffers
QuantumEntangledAndy May 15, 2023
3a783bf
Use only unique timestamps to calculate live
QuantumEntangledAndy May 15, 2023
6a980b4
Reduce target buffer size
QuantumEntangledAndy May 15, 2023
f5ba6e2
Imporve handoff between preprocess and live
QuantumEntangledAndy May 15, 2023
279c1c5
Do target live calculation for abstract buffer
QuantumEntangledAndy May 15, 2023
36f70c3
No smooth and extra debug
QuantumEntangledAndy May 15, 2023
78da59f
Change the way buffer time stamps are handled
QuantumEntangledAndy May 16, 2023
511e50f
Update the start time on restamp too
QuantumEntangledAndy May 16, 2023
2f74a72
Sign correction
QuantumEntangledAndy May 16, 2023
84e1053
Minimum stamp buffer size
QuantumEntangledAndy May 16, 2023
86f15f9
Handle jump to live even for a one frame buffer
QuantumEntangledAndy May 16, 2023
d61e48c
Full grouping for frames of the same time
QuantumEntangledAndy May 16, 2023
56ef79f
Yet another alteration to seek
QuantumEntangledAndy May 16, 2023
9473a8a
Correct buffer sorting, and reinit
QuantumEntangledAndy May 16, 2023
3b677f9
Refilling debug print correction
QuantumEntangledAndy May 16, 2023
f5ac615
Renable time smoothing
QuantumEntangledAndy May 16, 2023
951a822
Make buffer size configurable
QuantumEntangledAndy May 16, 2023
c2a5798
Change buffer over and undeful size
QuantumEntangledAndy May 16, 2023
99584ce
Slightly increase the MTU
QuantumEntangledAndy May 17, 2023
790eb65
Put a message about max bitrate in the log when buffer is exhausted
QuantumEntangledAndy May 17, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ gstreamer = "0.20.3"
gstreamer-app = "0.20.0"
gstreamer-rtsp = "0.20.0"
gstreamer-rtsp-server = { version = "0.20.3", features = ["v1_16"] }
is_sorted = "0.1.1"
itertools = "0.10.5"
lazy_static = "1.4.0"
log = { version = "0.4.17", features = [ "release_max_level_debug" ] }
neolink_core = { path = "crates/core", version = "0.5.10" }
Expand Down
2 changes: 1 addition & 1 deletion crates/core/src/bc_protocol/connection/discovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ struct UidLookupResults {

pub(crate) struct Discovery {}

const MTU: u32 = 1030;
const MTU: u32 = 1350;
lazy_static! {
static ref P2P_RELAY_HOSTNAMES: [&'static str; 10] = [
"p2p.reolink.com",
Expand Down
2 changes: 1 addition & 1 deletion crates/core/src/bc_protocol/connection/udpsource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use tokio_util::{
udp::UdpFramed,
};

const MTU: usize = 1030;
const MTU: usize = 1350;
const UDPDATA_HEADER_SIZE: usize = 20;

pub(crate) struct UdpSource {
Expand Down
16 changes: 16 additions & 0 deletions sample_config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,22 @@ address = "192.168.1.187:9000"
#
# print_format = "None"

# Internally neolink uses a buffer to improve delivery of frames at their actual times
# A large buffer can work even for large interupts in the connection with the camera
# A small buffer will reduce the latency introduced
# buffer_size: 100

# Over long periods of time the camera buffer can exhaust with no means of recovery
# to combat this a time stretching stratery is employed where the stream is slowed
# as the buffer is exhausted and sped up when full
# this can keep the camera and rtsp streams in sync and reduce buffer exhaustions
#
# HOWEVER if there is real latency issues (such as too high a bitrate)
# then smoothing can result in a stream appearing in slow motion
#
# you can disable and enable this feature here
# use_smoothing: true


[[cameras]]
name = "storage shed"
Expand Down
24 changes: 24 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,22 @@ pub(crate) struct CameraConfig {

#[serde(default = "default_update_time", alias = "time")]
pub(crate) update_time: bool,

#[validate(range(
min = 10,
max = 500,
message = "Invalid buffer size",
code = "buffer_size"
))]
#[serde(default = "default_buffer_size", alias = "size", alias = "buffer")]
pub(crate) buffer_size: usize,

#[serde(
default = "default_smoothing",
alias = "smoothing",
alias = "stretching"
)]
pub(crate) use_smoothing: bool,
}

#[derive(Debug, Deserialize, Validate, Clone)]
Expand Down Expand Up @@ -239,6 +255,14 @@ fn default_pause() -> PauseConfig {
}
}

fn default_smoothing() -> bool {
true
}

fn default_buffer_size() -> usize {
100
}

pub(crate) static RESERVED_NAMES: &[&str] = &["anyone", "anonymous"];
fn validate_username(name: &str) -> Result<(), ValidationError> {
if name.trim().is_empty() {
Expand Down
14 changes: 11 additions & 3 deletions src/rtsp/gst/factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,16 @@ glib::wrapper! {

impl Default for NeoMediaFactory {
fn default() -> Self {
Self::new()
Self::new(100, true)
}
}

impl NeoMediaFactory {
pub(crate) fn new() -> Self {
pub(crate) fn new(buffer_size: usize, use_smoothing: bool) -> Self {
let factory = Object::new::<NeoMediaFactory>();
factory.set_shared(false);
factory.imp().shared.set_buffer_size(buffer_size);
factory.imp().shared.set_use_smoothing(use_smoothing);
// factory.set_do_retransmission(false); // Can't use as the method is missing on the 32bit docker gst dll
factory.set_launch("videotestsrc pattern=\"snow\" ! video/x-raw,width=896,height=512,framerate=25/1 ! textoverlay name=\"inittextoverlay\" text=\"Stream not Ready\" valignment=top halignment=left font-desc=\"Sans, 32\" ! jpegenc ! rtpjpegpay name=pay0");
factory.set_suspend_mode(RTSPSuspendMode::None);
Expand Down Expand Up @@ -120,6 +122,8 @@ pub(crate) enum FactoryCommand {
BcMedia(BcMedia),
ClearBuffer,
JumpToLive,
Pause,
Resume,
}

pub(crate) struct NeoMediaFactoryImpl {
Expand Down Expand Up @@ -149,6 +153,7 @@ impl Default for NeoMediaFactoryImpl {
shared.clone(),
ReceiverStream::new(datarx),
ReceiverStream::new(rx_clientsender),
100,
);
threads.spawn(async move {
loop {
Expand Down Expand Up @@ -265,7 +270,10 @@ impl NeoMediaFactoryImpl {
bin.remove(&element)?;
}

let mut client_data = NeoMediaSender::new();
let mut client_data = NeoMediaSender::new(
self.shared.get_buffer_size(),
self.shared.get_use_smoothing(),
);

// Now contruct the actual ones
match (
Expand Down
Loading