use crate::impl_thread_safety;
pub type OnVideoPublishTiming = Box<dyn Fn(ffi::VideoPublishTimingEvent) + Send + Sync + 'static>;
pub type OnVideoSubscribeTiming =
Box<dyn Fn(ffi::VideoSubscribeTimingEvent) + Send + Sync + 'static>;
#[cxx::bridge(namespace = "livekit_ffi")]
pub mod ffi {
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum VideoPublishTimingStage {
EncoderUpload,
EncoderOutput,
WebrtcPacketize,
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum VideoSubscribeTimingStage {
WebrtcReceive,
DecoderUpload,
DecoderOutput,
}
#[derive(Debug, Clone, Copy)]
pub struct VideoPublishTimingEvent {
pub stage: VideoPublishTimingStage,
pub timestamp_us: u64,
pub capture_timestamp_us: u64,
pub frame_id: u32,
}
#[derive(Debug, Clone, Copy)]
pub struct VideoSubscribeTimingEvent {
pub stage: VideoSubscribeTimingStage,
pub timestamp_us: u64,
pub capture_timestamp_us: u64,
pub frame_id: u32,
}
unsafe extern "C++" {
include!("livekit/packet_trailer.h");
include!("livekit/rtp_sender.h");
include!("livekit/rtp_receiver.h");
include!("livekit/peer_connection_factory.h");
type RtpSender = crate::rtp_sender::ffi::RtpSender;
type RtpReceiver = crate::rtp_receiver::ffi::RtpReceiver;
type PeerConnectionFactory = crate::peer_connection_factory::ffi::PeerConnectionFactory;
pub type PacketTrailerHandler;
fn set_enabled(self: &PacketTrailerHandler, enabled: bool);
fn enabled(self: &PacketTrailerHandler) -> bool;
fn lookup_timestamp(self: &PacketTrailerHandler, rtp_timestamp: u32) -> u64;
fn last_lookup_frame_id(self: &PacketTrailerHandler) -> u32;
fn store_frame_metadata(
self: &PacketTrailerHandler,
capture_timestamp_us: i64,
user_timestamp: u64,
frame_id: u32,
);
fn set_publish_timing_observer(
self: &PacketTrailerHandler,
observer: Box<VideoPublishTimingObserverWrapper>,
);
fn clear_publish_timing_observer(self: &PacketTrailerHandler);
fn set_subscribe_timing_observer(
self: &PacketTrailerHandler,
observer: Box<VideoSubscribeTimingObserverWrapper>,
);
fn clear_subscribe_timing_observer(self: &PacketTrailerHandler);
fn emit_subscribe_timing(
self: &PacketTrailerHandler,
stage: VideoSubscribeTimingStage,
user_timestamp: u64,
frame_id: u32,
);
fn new_packet_trailer_sender(
peer_factory: SharedPtr<PeerConnectionFactory>,
sender: SharedPtr<RtpSender>,
) -> SharedPtr<PacketTrailerHandler>;
fn new_packet_trailer_receiver(
peer_factory: SharedPtr<PeerConnectionFactory>,
receiver: SharedPtr<RtpReceiver>,
) -> SharedPtr<PacketTrailerHandler>;
}
extern "Rust" {
type VideoPublishTimingObserverWrapper;
type VideoSubscribeTimingObserverWrapper;
fn on_publish_timing(
self: &VideoPublishTimingObserverWrapper,
event: VideoPublishTimingEvent,
);
fn on_subscribe_timing(
self: &VideoSubscribeTimingObserverWrapper,
event: VideoSubscribeTimingEvent,
);
}
}
impl_thread_safety!(ffi::PacketTrailerHandler, Send + Sync);
pub struct VideoPublishTimingObserverWrapper {
observer: OnVideoPublishTiming,
}
impl VideoPublishTimingObserverWrapper {
pub fn new(observer: OnVideoPublishTiming) -> Self {
Self { observer }
}
fn on_publish_timing(&self, event: ffi::VideoPublishTimingEvent) {
(self.observer)(event);
}
}
pub struct VideoSubscribeTimingObserverWrapper {
observer: OnVideoSubscribeTiming,
}
impl VideoSubscribeTimingObserverWrapper {
pub fn new(observer: OnVideoSubscribeTiming) -> Self {
Self { observer }
}
fn on_subscribe_timing(&self, event: ffi::VideoSubscribeTimingEvent) {
(self.observer)(event);
}
}