Handle PictureLossIndication (#17)

Handle PLI to send a keyframe whenever the client requests. This should
fix image freezes.
This commit is contained in:
Harry
2022-11-25 14:24:19 -05:00
committed by GitHub
parent 7c6bfd15e1
commit 9b4d5d2038
6 changed files with 49 additions and 4 deletions
Generated
+1
View File
@@ -1540,6 +1540,7 @@ dependencies = [
"itertools",
"libc",
"log",
"rtcp",
"serde",
"serde_json",
"tokio",
+1
View File
@@ -27,6 +27,7 @@ ac-ffmpeg = { git = "https://github.com/mira-screen-share/rust-ac-ffmpeg", branc
toml = "0.5.9"
itertools = "0.10.5"
howlong = "0.1.7"
rtcp = "0.7.1"
[target.'cfg(target_os = "macos")'.dependencies]
libc = "0.2.108"
+1 -1
View File
@@ -13,7 +13,7 @@ credential_type = "Password"
[encoder]
encoder = "libx264"
yuv_input = true
pixel_format = "yuv420p"
[encoder.options]
profile = "baseline"
+2 -2
View File
@@ -1,6 +1,6 @@
signaller_url = "wss://ws.mirashare.app"
viewer_url = "https://mirashare.app/"
max_fps = 60
max_fps = 30
[[ice_servers]]
urls = ["stun:stun.l.google.com:19302"]
@@ -13,7 +13,7 @@ credential_type = "Password"
[encoder]
encoder = "h264_nvenc"
yuv_input = false
pixel_format = "bgra"
[encoder.options]
profile = "baseline"
+2
View File
@@ -2,6 +2,8 @@ use failure::format_err;
use crate::capture::DisplayInfo;
use crate::result::Result;
use failure::format_err;
use std::mem;
use super::ffi::*;
+42 -1
View File
@@ -1,6 +1,8 @@
use crate::inputs::InputHandler;
use log::{debug, info};
use rtcp::payload_feedbacks::picture_loss_indication::PictureLossIndication;
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
use webrtc::ice_transport::ice_candidate::RTCIceCandidate;
@@ -11,6 +13,11 @@ use webrtc::track::track_local::track_local_static_sample::TrackLocalStaticSampl
use crate::signaller::SignallerPeer;
use crate::Result;
use rtcp::packet::unmarshal;
use rtcp::payload_feedbacks::full_intra_request::FullIntraRequest;
use rtcp::payload_feedbacks::receiver_estimated_maximum_bitrate::ReceiverEstimatedMaximumBitrate;
use rtcp::receiver_report::ReceiverReport;
pub struct WebRTCPeer {}
@@ -24,7 +31,41 @@ impl WebRTCPeer {
) -> Result<Self> {
debug!("Initializing a new WebRTC peer");
peer_connection.add_track(video_track).await?;
let rtp_sender = peer_connection.add_track(video_track).await?;
let encoder_force_idr_clone = encoder_force_idr.clone();
tokio::spawn(async move {
let mut rtcp_buf = vec![0u8; 1500];
while let Ok((size, _)) = rtp_sender.read(&mut rtcp_buf).await {
let mut buffer = &rtcp_buf[..size];
let pkts = unmarshal(&mut buffer).unwrap();
for pkt in pkts {
if let Some(_pli) = pkt.as_any().downcast_ref::<PictureLossIndication>() {
info!("PLI received");
encoder_force_idr_clone.store(true, std::sync::atomic::Ordering::Relaxed);
} else if let Some(_fir) = pkt.as_any().downcast_ref::<FullIntraRequest>() {
info!("FIR received");
encoder_force_idr_clone.store(true, std::sync::atomic::Ordering::Relaxed);
} else if let Some(report) = pkt.as_any().downcast_ref::<ReceiverReport>() {
let report = report.reports.first().unwrap();
trace!(
"RR: jitter: {:.2} ms, lost: {}, delay: {:.2} ms",
(report.jitter as f64 / 90_000. * 1000.),
report.total_lost,
(report.delay as f64 / 65536. * 1000.)
);
} else if let Some(bitrate) = pkt
.as_any()
.downcast_ref::<ReceiverEstimatedMaximumBitrate>()
{
trace!("Estimated bitrate: {:#?}", bitrate.bitrate);
} else {
warn!("Unknown RTCP packet: {:#?}", pkt);
}
}
}
Result::<()>::Ok(())
});
let data_channel = peer_connection.create_data_channel("control", None).await?;
let input_handler = input_handler.clone();