use std::fmt;
use std::ops::RangeInclusive;
use std::time::Instant;
use crate::packet::MediaKind;
use crate::rtp_::{Direction, ExtensionValues, MediaTime, Mid, Pt, Rid, SenderInfo, SeqNo};
use crate::sdp::SimulcastLayer as SdpSimulcastLayer;
use crate::sdp::{RestrictionId, Simulcast as SdpSimulcast, SimulcastGroups as SdpSimulcastGroups};
use super::PayloadParams;
use crate::format::CodecExtra;
impl From<&SdpSimulcastLayer> for SimulcastLayer {
fn from(layer: &SdpSimulcastLayer) -> Self {
SimulcastLayer {
rid: Rid::from(layer.restriction_id.0.as_ref()),
attributes: layer.attributes.clone(),
}
}
}
impl From<&SimulcastLayer> for SdpSimulcastLayer {
fn from(layer: &SimulcastLayer) -> Self {
SdpSimulcastLayer {
restriction_id: RestrictionId::new_active(layer.rid.to_string()),
attributes: layer.attributes.clone(),
}
}
}
impl From<SdpSimulcast> for Simulcast {
fn from(s: SdpSimulcast) -> Self {
let send = s.send.iter().map(Into::into).collect();
let recv = s.recv.iter().map(Into::into).collect();
Simulcast { send, recv }
}
}
#[derive(Debug, PartialEq, Eq)]
pub struct MediaAdded {
pub mid: Mid,
pub kind: MediaKind,
pub direction: Direction,
pub simulcast: Option<Simulcast>,
}
#[derive(Debug, PartialEq, Eq)]
pub struct MediaChanged {
pub mid: Mid,
pub direction: Direction,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Simulcast {
pub send: Vec<SimulcastLayer>,
pub recv: Vec<SimulcastLayer>,
}
impl Simulcast {
pub fn new() -> Simulcast {
Simulcast {
send: vec![],
recv: vec![],
}
}
}
impl Simulcast {
pub fn add_send_layer(&mut self, layer: SimulcastLayer) {
self.send.push(layer);
}
pub fn add_recv_layer(&mut self, layer: SimulcastLayer) {
self.send.push(layer);
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct SimulcastLayer {
pub rid: Rid,
pub attributes: Option<Vec<(String, String)>>,
}
impl SimulcastLayer {
pub fn new(rid: &str) -> SimulcastLayer {
SimulcastLayer {
rid: Rid::from(rid),
attributes: None,
}
}
pub fn new_with_attributes(rid: &str) -> SimulcastLayerBuilder {
SimulcastLayerBuilder {
rid: Rid::from(rid),
attributes: vec![],
}
}
}
pub struct SimulcastLayerBuilder {
rid: Rid,
attributes: Vec<(String, String)>,
}
impl SimulcastLayerBuilder {
pub fn max_width(mut self, max_width: u32) -> Self {
self.update_or_insert("max-width", max_width.to_string());
self
}
pub fn max_height(mut self, max_height: u32) -> Self {
self.update_or_insert("max-height", max_height.to_string());
self
}
pub fn max_br(mut self, max_br: u32) -> Self {
self.update_or_insert("max-br", max_br.to_string());
self
}
pub fn max_fps(mut self, max_fps: u32) -> Self {
self.update_or_insert("max-fps", max_fps.to_string());
self
}
pub fn custom(mut self, key: &str, value: &str) -> Self {
self.update_or_insert(key, value.to_string());
self
}
pub fn build(self) -> SimulcastLayer {
SimulcastLayer {
rid: self.rid,
attributes: if self.attributes.is_empty() {
None
} else {
Some(self.attributes)
},
}
}
fn update_or_insert(&mut self, key: &str, value: String) {
for (k, v) in &mut self.attributes {
if k == key {
*v = value;
return;
}
}
self.attributes.push((key.to_string(), value));
}
}
impl Simulcast {
pub(crate) fn into_sdp(self) -> SdpSimulcast {
SdpSimulcast {
send: SdpSimulcastGroups(self.send.iter().map(Into::into).collect()),
recv: SdpSimulcastGroups(self.recv.iter().map(Into::into).collect()),
is_munged: false,
}
}
}
#[derive(PartialEq, Eq)]
pub struct MediaData {
pub mid: Mid,
pub pt: Pt,
pub rid: Option<Rid>,
pub params: PayloadParams,
pub time: MediaTime,
pub network_time: Instant,
pub seq_range: RangeInclusive<SeqNo>,
pub contiguous: bool,
pub data: Vec<u8>,
pub ext_vals: ExtensionValues,
pub codec_extra: CodecExtra,
pub last_sender_info: Option<SenderInfo>,
pub audio_start_of_talk_spurt: bool,
}
impl MediaData {
pub fn is_keyframe(&self) -> bool {
match self.codec_extra {
CodecExtra::None => false,
CodecExtra::H264(h264_extra) => h264_extra.is_keyframe,
CodecExtra::H265(h265_extra) => h265_extra.is_keyframe,
CodecExtra::Vp8(vp8_extra) => vp8_extra.is_keyframe,
CodecExtra::Vp9(vp9_extra) => vp9_extra.is_keyframe,
CodecExtra::Av1(av1_extra) => av1_extra.is_keyframe,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct KeyframeRequest {
pub mid: Mid,
pub rid: Option<Rid>,
pub kind: KeyframeRequestKind,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KeyframeRequestKind {
Pli,
Fir,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SenderFeedback {
pub mid: Mid,
pub rid: Option<Rid>,
pub received_at: Instant,
pub sender_info: SenderInfo,
}
impl fmt::Debug for MediaData {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("MediaData")
.field("mid", &self.mid)
.field("pt", &self.pt)
.field("rid", &self.rid)
.field("time", &self.time)
.field("len", &self.data.len())
.finish()
}
}