Skip to content

Question about latency #281

Open
Open
@stellanhaglund

Description

@stellanhaglund

I'm doing a quick test to stream a recorded screen over webrtc but I'm experiencing multi second latencies, if you have any ideas that would help a lot!

here's the poc for the capturing part.


    thread::spawn( move ||  {
        let displays = Display::all().unwrap();
        let display = displays.into_iter().nth(0).unwrap();
    
        let mut capturer = Capturer::new(display).unwrap();
        let width = capturer.width() as u32;
        let height = capturer.height() as u32;    
    
        let (vpx_codec, mux_codec) = match Codec::Vp9 {
            Codec::Vp8 => (vpx_encode::VideoCodecId::VP8, mux::VideoCodecId::VP8),
            Codec::Vp9 => (vpx_encode::VideoCodecId::VP9, mux::VideoCodecId::VP9),
        };    
    
        let mut vpx = vpx_encode::Encoder::new(vpx_encode::Config {
            width: width,
            height: height,
            timebase: [1, 1000],
            bitrate: 5000,
            codec: vpx_codec,
        }).unwrap();            

        let start = Instant::now();
        let mut yuv = Vec::new();
        let spf = Duration::from_nanos(1_000_000_000 / 30);

        loop {

            let now = Instant::now();
            let time = now - start;        
            
            match capturer.frame() {
                
                Ok(frame) => {

                    let ms = time.as_secs() * 1000 + time.subsec_millis() as u64;

                    convert::argb_to_i420(width as usize, height as usize, &frame, &mut yuv);
                    
                    for frame in vpx.encode(ms as i64, &yuv).unwrap() {
                        let owned = frame.data.to_vec();
                        frame_tx.send(owned).expect("msg");
                    }
                }
                _ => { }
            }        

            // let dt = now.elapsed();
            // if dt < spf {
            //     thread::sleep(spf - dt);
            // }            
        }

    });    
    

And here's the reciever.

    
        tokio::spawn(async move {
        // Wait for connection established
        let _ = notify_video.notified().await;

        let sleep_time = Duration::from_millis(
            ((1000 * 1) / 30) as u64,
        );
        let mut ticker = tokio::time::interval(sleep_time);

        for frame in frame_rx {

            let mut byte_frame = BytesMut::with_capacity(frame.len());
            byte_frame.put(&frame[..]);                

            video_track
                .write_sample(&Sample {
                    data: byte_frame.freeze(),
                    duration: Duration::from_secs(1),
                    ..Default::default()
                })
                .await?;                

            let _ = ticker.tick().await;

        }

        Result::<()>::Ok(())
    });
    

I've tried both with and without the waiting parts.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions