hyperspeed_broadcast/rtc/
codecs.rs

1use std::num::{NonZeroU32, NonZeroU8};
2
3use mediasoup::router::RouterOptions;
4use mediasoup::rtp_parameters::{MimeTypeAudio, MimeTypeVideo, RtcpFeedback, RtpCodecCapability, RtpCodecParametersParameters};
5
6use super::routers::DataSource;
7
8pub struct VideoCodec {
9    pub mime_type: MimeTypeVideo,
10    pub clock_rate: u32,
11    pub parameters: RtpCodecParametersParameters,
12    pub rtcp_feedback: Vec<RtcpFeedback>
13}
14
15impl VideoCodec {
16    pub fn from(codec: &str) -> VideoCodec {
17        let mime_type = match codec {
18            "H264" => MimeTypeVideo::H264,
19            _ => unimplemented!()
20        };
21
22        let mut parameters = match mime_type {
23            MimeTypeVideo::H264 => RtpCodecParametersParameters::from([
24                ("packetization-mode", 1_u32.into()),
25                ("level-asymmetry-allowed", 1_u32.into())
26            ]),
27            _ => unreachable!()
28        };
29
30        parameters.insert("profile-level-id", "42e01f");
31
32        let clock_rate = match mime_type {
33            MimeTypeVideo::H264 => 90_000,
34            _ => unreachable!()
35        };
36
37        let rtcp_feedback = match mime_type {
38            MimeTypeVideo::H264 => vec! [
39                RtcpFeedback::Nack,
40                RtcpFeedback::NackPli,
41                RtcpFeedback::CcmFir,
42                RtcpFeedback::GoogRemb,
43                RtcpFeedback::TransportCc,
44            ],
45            _ => unreachable!()
46        };
47
48        VideoCodec {
49            mime_type,
50            clock_rate,
51            parameters,
52            rtcp_feedback
53        }
54    }
55}
56
57pub struct AudioCodec {
58    pub mime_type: MimeTypeAudio,
59    pub clock_rate: u32,
60    pub parameters: RtpCodecParametersParameters,
61    pub rtcp_feedback: Vec<RtcpFeedback>
62}
63
64impl AudioCodec {
65    pub fn from(codec: &str) -> AudioCodec {
66        let mime_type = match codec {
67            "OPUS" => MimeTypeAudio::Opus,
68            _ => unimplemented!()
69        };
70
71        let parameters = RtpCodecParametersParameters::default();
72        let rtcp_feedback = Vec::new();
73
74        let clock_rate = match mime_type {
75            MimeTypeAudio::Opus => 48_000,
76            _ => unreachable!()
77        };
78
79        AudioCodec {
80            mime_type,
81            clock_rate,
82            parameters,
83            rtcp_feedback
84        }
85    }
86}
87
88pub fn init_codecs(options: &mut RouterOptions, source: &DataSource) {
89    match source {
90        DataSource::Ftl(handshake) => {
91            if let Some(video) = &handshake.video {
92                let VideoCodec { mime_type, clock_rate, parameters, rtcp_feedback }
93                    = VideoCodec::from(&video.codec);
94
95                options.media_codecs.push(
96                    RtpCodecCapability::Video {
97                        mime_type,
98                        preferred_payload_type: None,
99                        clock_rate: NonZeroU32::new(clock_rate).unwrap(),
100                        parameters,
101                        rtcp_feedback
102                    }
103                );
104            }
105
106            if let Some(audio) = &handshake.audio {
107                let AudioCodec { mime_type, clock_rate, parameters, rtcp_feedback }
108                    = AudioCodec::from(&audio.codec);
109
110                options.media_codecs.push(
111                    RtpCodecCapability::Audio {
112                        mime_type,
113                        preferred_payload_type: None,
114                        clock_rate: NonZeroU32::new(clock_rate).unwrap(),
115                        channels: NonZeroU8::new(2).unwrap(),
116                        parameters,
117                        rtcp_feedback
118                    }
119                );
120            }
121        }
122    }
123}