tello_edu/
video.rs

1use tokio::{spawn, task};
2use tokio::sync::mpsc;
3use tokio::net::UdpSocket;
4use bytebuffer::ByteBuffer;
5
6use crate::errors::Result;
7
8pub const VIDEO_WIDTH:u32 = 960;
9pub const VIDEO_HEIGHT:u32 = 720; 
10
11const VIDEO_UDP_PORT:u32 = 11111;
12const MAX_CHUNK_SIZE:usize = 1460;
13
14
15pub type TelloVideoSender = mpsc::UnboundedSender<TelloVideoFrame>;
16pub type TelloVideoReceiver = mpsc::UnboundedReceiver<TelloVideoFrame>;
17
18pub fn make_tello_video_channel() -> (TelloVideoSender, TelloVideoReceiver) {
19    mpsc::unbounded_channel()
20}
21
22/// A frame of video from the drone.
23#[derive(Debug)]
24pub struct TelloVideoFrame {
25    pub data: Vec<u8>
26}
27
28#[derive(Debug)]
29pub(crate) struct VideoListener {
30    task: task::JoinHandle<()>
31}   
32
33impl VideoListener {
34    pub(crate) async fn start_listening(sender:TelloVideoSender) -> Result<Self> { 
35        let local_address = format!("0.0.0.0:{VIDEO_UDP_PORT}");
36        println!("[Video] START LISTENING at {local_address}");
37
38        let sock = UdpSocket::bind(&local_address).await?;
39
40        let task = spawn(async move {
41            let mut buf = ByteBuffer::new();
42            loop {
43                let s = &sock;
44                let mut chunk = vec![0; MAX_CHUNK_SIZE]; //Vec::with_capacity(MAX_CHUNK_SIZE);        
45                let n = s.recv(&mut chunk).await.unwrap();
46                if n != 0 {
47                    buf.write_bytes(&chunk);
48
49                    if n < MAX_CHUNK_SIZE {
50                        let frame = TelloVideoFrame { data: buf.into_vec() };
51                        sender.send(frame).unwrap();
52                        buf = ByteBuffer::new();
53                    }
54                }
55            }
56        });
57
58        Ok(Self { task })
59    }
60
61    pub(crate) async fn stop_listening(&self) -> Result<()> {
62        println!("[Video] STOP LISTENING");
63        self.task.abort();
64        // TODO?
65        // let _err = self.task.await;
66        Ok(())
67    }
68 }