183 lines
5.5 KiB
Rust
183 lines
5.5 KiB
Rust
use crate::proto::TrackType;
|
|
use crate::proto::{TrackInfo, TrackSource as ProtoTrackSource};
|
|
use crate::room::id::ParticipantSid;
|
|
use crate::room::id::TrackSid;
|
|
use crate::room::track::local_track::LocalTrackHandle;
|
|
use crate::room::track::remote_track::RemoteTrackHandle;
|
|
use crate::room::track::{TrackHandle, TrackKind, TrackSource};
|
|
use crate::utils::wrap_variants;
|
|
use parking_lot::Mutex;
|
|
use std::sync::atomic::{AtomicBool, AtomicU8, Ordering};
|
|
use std::sync::Arc;
|
|
|
|
use super::track::TrackDimension;
|
|
|
|
pub(crate) trait TrackPublicationInternalTrait {
|
|
fn update_track(&self, track: Option<TrackHandle>);
|
|
fn update_info(&self, info: TrackInfo);
|
|
}
|
|
|
|
pub trait TrackPublicationTrait {
|
|
fn name(&self) -> String;
|
|
fn sid(&self) -> TrackSid;
|
|
fn kind(&self) -> TrackKind;
|
|
fn source(&self) -> TrackSource;
|
|
fn simulcasted(&self) -> bool;
|
|
}
|
|
|
|
pub(super) struct TrackPublicationShared {
|
|
pub(super) track: Mutex<Option<TrackHandle>>,
|
|
pub(super) name: Mutex<String>,
|
|
pub(super) sid: Mutex<TrackSid>,
|
|
pub(super) kind: AtomicU8, // Casted to TrackKind
|
|
pub(super) source: AtomicU8, // Casted to TrackSource
|
|
pub(super) simulcasted: AtomicBool,
|
|
pub(super) dimension: Mutex<TrackDimension>,
|
|
pub(super) mime_type: Mutex<String>,
|
|
pub(super) participant: ParticipantSid, // TODO(theomonnom) Use WeakParticipant instead
|
|
}
|
|
|
|
impl TrackPublicationShared {
|
|
pub fn new(info: TrackInfo, participant: ParticipantSid, track: Option<TrackHandle>) -> Arc<Self> {
|
|
Arc::new(Self {
|
|
track: Mutex::new(track),
|
|
name: Mutex::new(info.name),
|
|
sid: Mutex::new(info.sid.into()),
|
|
kind: AtomicU8::new(TrackKind::from(TrackType::from_i32(info.r#type).unwrap()) as u8),
|
|
source: AtomicU8::new(TrackSource::from(
|
|
ProtoTrackSource::from_i32(info.source).unwrap(),
|
|
) as u8),
|
|
simulcasted: AtomicBool::new(info.simulcast),
|
|
dimension: Mutex::new(TrackDimension(info.width, info.height)),
|
|
mime_type: Mutex::new(info.mime_type),
|
|
participant,
|
|
})
|
|
}
|
|
|
|
pub fn update_info(&self, info: TrackInfo) {
|
|
*self.name.lock() = info.name;
|
|
*self.sid.lock() = info.sid.into();
|
|
self.kind.store(
|
|
TrackKind::from(TrackType::from_i32(info.r#type).unwrap()) as u8,
|
|
Ordering::SeqCst,
|
|
);
|
|
self.source.store(
|
|
TrackSource::from(ProtoTrackSource::from_i32(info.source).unwrap()) as u8,
|
|
Ordering::SeqCst,
|
|
);
|
|
self.simulcasted.store(info.simulcast, Ordering::SeqCst);
|
|
*self.dimension.lock() = TrackDimension(info.width, info.height);
|
|
*self.mime_type.lock() = info.mime_type;
|
|
}
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub enum TrackPublication {
|
|
Local(LocalTrackPublication),
|
|
Remote(RemoteTrackPublication),
|
|
}
|
|
|
|
impl TrackPublication {
|
|
pub fn track(&self) -> Option<TrackHandle> {
|
|
// Not calling Local/Remote function here, we don't need "cast"
|
|
match self {
|
|
TrackPublication::Local(p) => p.shared.track.lock().clone(),
|
|
TrackPublication::Remote(p) => p.shared.track.lock().clone(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl TrackPublicationInternalTrait for TrackPublication {
|
|
wrap_variants!(
|
|
[Local, Remote]
|
|
fnc!(update_track, (), [track: Option<TrackHandle>]);
|
|
fnc!(update_info, (), [info: TrackInfo]);
|
|
);
|
|
}
|
|
|
|
impl TrackPublicationTrait for TrackPublication {
|
|
wrap_variants!(
|
|
[Local, Remote]
|
|
fnc!(sid, TrackSid, []);
|
|
fnc!(name, String, []);
|
|
fnc!(kind, TrackKind, []);
|
|
fnc!(source, TrackSource, []);
|
|
fnc!(simulcasted, bool, []);
|
|
);
|
|
}
|
|
|
|
macro_rules! impl_publication_trait {
|
|
($x:ident) => {
|
|
impl TrackPublicationInternalTrait for $x {
|
|
fn update_track(&self, track: Option<TrackHandle>) {
|
|
*self.shared.track.lock() = track;
|
|
}
|
|
|
|
fn update_info(&self, info: TrackInfo) {
|
|
self.shared.update_info(info);
|
|
}
|
|
}
|
|
|
|
impl TrackPublicationTrait for $x {
|
|
fn name(&self) -> String {
|
|
self.shared.name.lock().clone()
|
|
}
|
|
|
|
fn sid(&self) -> TrackSid {
|
|
self.shared.sid.lock().clone()
|
|
}
|
|
|
|
fn kind(&self) -> TrackKind {
|
|
self.shared.kind.load(Ordering::SeqCst).into()
|
|
}
|
|
|
|
fn source(&self) -> TrackSource {
|
|
self.shared.source.load(Ordering::SeqCst).into()
|
|
}
|
|
|
|
fn simulcasted(&self) -> bool {
|
|
self.shared.simulcasted.load(Ordering::SeqCst)
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct LocalTrackPublication {
|
|
shared: Arc<TrackPublicationShared>,
|
|
}
|
|
|
|
impl LocalTrackPublication {
|
|
pub fn track(&self) -> Option<LocalTrackHandle> {
|
|
self.shared
|
|
.track
|
|
.lock()
|
|
.clone()
|
|
.map(|local_track| local_track.try_into().unwrap())
|
|
}
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct RemoteTrackPublication {
|
|
shared: Arc<TrackPublicationShared>,
|
|
}
|
|
|
|
impl RemoteTrackPublication {
|
|
pub fn new(info: TrackInfo, participant: ParticipantSid, track: Option<TrackHandle>) -> Self {
|
|
Self {
|
|
shared: TrackPublicationShared::new(info, participant, track),
|
|
}
|
|
}
|
|
|
|
pub fn track(&self) -> Option<RemoteTrackHandle> {
|
|
self.shared
|
|
.track
|
|
.lock()
|
|
.clone()
|
|
.map(|track| track.try_into().unwrap())
|
|
}
|
|
}
|
|
|
|
impl_publication_trait!(LocalTrackPublication);
|
|
impl_publication_trait!(RemoteTrackPublication);
|