mod av1;
mod codec;
mod h264;
mod h265;
mod vp9;
pub use av1::*;
pub use codec::*;
pub use h264::*;
pub use h265::*;
pub use vp9::*;
use std::collections::{BTreeMap, btree_map};
use bytes::Bytes;
use serde::{Deserialize, Serialize};
use serde_with::{DisplayFromStr, hex::Hex};
use crate::catalog::Container;
#[serde_with::serde_as]
#[serde_with::skip_serializing_none]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)]
#[serde(rename_all = "camelCase")]
pub struct Video {
pub renditions: BTreeMap<String, VideoConfig>,
#[serde(default)]
pub display: Option<Display>,
#[serde(default)]
pub rotation: Option<f64>,
#[serde(default)]
pub flip: Option<bool>,
}
impl Video {
pub fn insert(&mut self, name: &str, config: VideoConfig) -> crate::Result<()> {
let btree_map::Entry::Vacant(entry) = self.renditions.entry(name.to_string()) else {
return Err(crate::Error::Duplicate(name.to_string()));
};
entry.insert(config);
Ok(())
}
#[deprecated(
note = "use BroadcastProducer::unique_track to create the track, then insert into the catalog when initialized"
)]
pub fn create_track(&mut self, extension: &str, config: VideoConfig) -> moq_lite::Track {
for i in 0.. {
let name = match extension {
"" => format!("video{}", i),
extension => format!("video{}.{}", i, extension),
};
if let btree_map::Entry::Vacant(entry) = self.renditions.entry(name.clone()) {
entry.insert(config.clone());
return moq_lite::Track { name, priority: 1 };
}
}
unreachable!("no available video track name");
}
pub fn remove(&mut self, name: &str) -> Option<VideoConfig> {
self.renditions.remove(name)
}
#[deprecated(note = "use remove() instead")]
pub fn remove_track(&mut self, track: &moq_lite::Track) -> Option<VideoConfig> {
self.remove(&track.name)
}
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Display {
pub width: u32,
pub height: u32,
}
#[serde_with::serde_as]
#[serde_with::skip_serializing_none]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct VideoConfig {
#[serde_as(as = "DisplayFromStr")]
pub codec: VideoCodec,
#[serde(default)]
#[serde_as(as = "Option<Hex>")]
pub description: Option<Bytes>,
pub coded_width: Option<u32>,
pub coded_height: Option<u32>,
pub display_ratio_width: Option<u32>,
pub display_ratio_height: Option<u32>,
#[serde(default)]
pub bitrate: Option<u64>,
#[serde(default)]
pub framerate: Option<f64>,
#[serde(default)]
pub optimize_for_latency: Option<bool>,
#[serde(default)]
pub container: Container,
#[serde(default)]
pub jitter: Option<moq_lite::Time>,
}