fix(webrtc): propagate poll_output error as cleanup signal to prevent zombie state (closes #14)
This commit is contained in:
@@ -246,8 +246,14 @@ impl WebRtcState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_h264_frame(&mut self, data: &[u8], frame_number: u64, fps: u32) -> Result<()> {
|
pub fn write_h264_frame(&mut self, data: &[u8], frame_number: u64, fps: u32) -> Result<()> {
|
||||||
if let Some(inner) = self.inner.as_mut() {
|
let should_destroy = if let Some(inner) = self.inner.as_mut() {
|
||||||
inner.write_h264_frame(data, frame_number, fps)?;
|
inner.write_h264_frame(data, frame_number, fps)?
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
if should_destroy {
|
||||||
|
tracing::warn!("WebRTC connection failed during write; clearing connection state");
|
||||||
|
self.inner = None;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -379,7 +385,8 @@ impl WebRtcInner {
|
|||||||
Ok(Output::Timeout(_t)) => break,
|
Ok(Output::Timeout(_t)) => break,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
tracing::error!("rtc.poll_output error: {e}");
|
tracing::error!("rtc.poll_output error: {e}");
|
||||||
break;
|
self.connected = false;
|
||||||
|
return Ok(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -423,23 +430,23 @@ impl WebRtcInner {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_h264_frame(&mut self, data: &[u8], frame_number: u64, fps: u32) -> Result<()> {
|
fn write_h264_frame(&mut self, data: &[u8], frame_number: u64, fps: u32) -> Result<bool> {
|
||||||
if !self.connected {
|
if !self.connected {
|
||||||
return Ok(());
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mid = match self.video_mid {
|
let mid = match self.video_mid {
|
||||||
Some(m) => m,
|
Some(m) => m,
|
||||||
None => {
|
None => {
|
||||||
tracing::warn!("write_h264: no video_mid");
|
tracing::warn!("write_h264: no video_mid");
|
||||||
return Ok(());
|
return Ok(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let pt = match self.video_pt {
|
let pt = match self.video_pt {
|
||||||
Some(p) => p,
|
Some(p) => p,
|
||||||
None => {
|
None => {
|
||||||
tracing::warn!("write_h264: no video_pt");
|
tracing::warn!("write_h264: no video_pt");
|
||||||
return Ok(());
|
return Ok(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -449,7 +456,7 @@ impl WebRtcInner {
|
|||||||
"write_h264: skipping non-IDR frame ({} bytes), waiting for keyframe",
|
"write_h264: skipping non-IDR frame ({} bytes), waiting for keyframe",
|
||||||
data.len()
|
data.len()
|
||||||
);
|
);
|
||||||
return Ok(());
|
return Ok(false);
|
||||||
}
|
}
|
||||||
tracing::info!(
|
tracing::info!(
|
||||||
"write_h264: got IDR keyframe ({} bytes), starting playback",
|
"write_h264: got IDR keyframe ({} bytes), starting playback",
|
||||||
@@ -468,7 +475,7 @@ impl WebRtcInner {
|
|||||||
Some(w) => w,
|
Some(w) => w,
|
||||||
None => {
|
None => {
|
||||||
tracing::warn!("write_h264: no writer for mid={mid}");
|
tracing::warn!("write_h264: no writer for mid={mid}");
|
||||||
return Ok(());
|
return Ok(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -482,9 +489,9 @@ impl WebRtcInner {
|
|||||||
.write(pt, Instant::now(), rtp_time, data)
|
.write(pt, Instant::now(), rtp_time, data)
|
||||||
.map_err(|e| anyhow::anyhow!("writer.write: {e}"))?;
|
.map_err(|e| anyhow::anyhow!("writer.write: {e}"))?;
|
||||||
|
|
||||||
self.poll_rtc()?;
|
let should_destroy = self.poll_rtc()?;
|
||||||
|
|
||||||
Ok(())
|
Ok(should_destroy)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_connected(&self) -> bool {
|
fn is_connected(&self) -> bool {
|
||||||
|
|||||||
Reference in New Issue
Block a user