@@ -27,6 +27,8 @@ use webrtc::track::track_local::TrackLocal;
2727const ANNEX_B_START_CODE : & [ u8 ] = & [ 0 , 0 , 0 , 1 ] ;
2828const DEFAULT_STUN_URL : & str = "stun:stun.l.google.com:19302" ;
2929const WEBRTC_CONTROL_CHANNEL_LABEL : & str = "simdeck-control" ;
30+ const WEBRTC_BOOTSTRAP_KEYFRAME_INTERVAL : Duration = Duration :: from_millis ( 150 ) ;
31+ const WEBRTC_BOOTSTRAP_KEYFRAME_REPEATS : u8 = 8 ;
3032const WEBRTC_MIN_REFRESH_INTERVAL : Duration = Duration :: from_millis ( 16 ) ;
3133const WEBRTC_MAX_REFRESH_INTERVAL : Duration = Duration :: from_millis ( 100 ) ;
3234const WEBRTC_WRITE_TIMEOUT : Duration = Duration :: from_millis ( 120 ) ;
@@ -454,11 +456,14 @@ impl WebRtcMediaStream {
454456 mut cancellation,
455457 } = self ;
456458 let mut rx = session. subscribe ( ) ;
459+ let mut latest_keyframe = first_frame. clone ( ) ;
457460 let mut last_sequence = 0u64 ;
458461 let mut send_timing = WebRtcSendTiming :: new ( ) ;
459462 let mut peer_state_interval = time:: interval ( Duration :: from_millis ( 250 ) ) ;
463+ let mut bootstrap_sleep = Box :: pin ( time:: sleep ( WEBRTC_BOOTSTRAP_KEYFRAME_INTERVAL ) ) ;
460464 let mut refresh_sleep = Box :: pin ( time:: sleep ( WEBRTC_MIN_REFRESH_INTERVAL ) ) ;
461465 let mut adaptive_refresh_interval = WEBRTC_MIN_REFRESH_INTERVAL ;
466+ let mut bootstrap_frames_remaining = WEBRTC_BOOTSTRAP_KEYFRAME_REPEATS ;
462467 let mut waiting_for_keyframe = false ;
463468 let _guard = WebRtcMetricsGuard :: new ( state. metrics . clone ( ) ) ;
464469
@@ -486,6 +491,21 @@ impl WebRtcMediaStream {
486491 break ;
487492 }
488493 }
494+ _ = & mut bootstrap_sleep, if bootstrap_frames_remaining > 0 => {
495+ if let Err ( error) = write_frame_sample(
496+ & video_track,
497+ & latest_keyframe,
498+ WEBRTC_BOOTSTRAP_KEYFRAME_INTERVAL ,
499+ ) . await {
500+ warn!( "WebRTC bootstrap keyframe write failed for {udid}: {error}" ) ;
501+ break ;
502+ }
503+ bootstrap_frames_remaining = bootstrap_frames_remaining. saturating_sub( 1 ) ;
504+ bootstrap_sleep
505+ . as_mut( )
506+ . reset( time:: Instant :: now( ) + WEBRTC_BOOTSTRAP_KEYFRAME_INTERVAL ) ;
507+ state. metrics. frames_sent. fetch_add( 1 , Ordering :: Relaxed ) ;
508+ }
489509 _ = & mut refresh_sleep => {
490510 session. request_refresh( ) ;
491511 refresh_sleep
@@ -520,6 +540,7 @@ impl WebRtcMediaStream {
520540 continue ;
521541 }
522542 if frame. is_keyframe {
543+ latest_keyframe = frame. clone( ) ;
523544 waiting_for_keyframe = false ;
524545 }
525546 let duration = send_timing. duration_for( & frame) ;
0 commit comments