RtpTransceiver bindings & requirements for publishing tracks (#39)
- RtpSender
- RtpReceiver
- RtpTransceiver
- RtpParameters
- VideoFrameBuilder
- Interior mutability on c++ side
- Cleanup bindings ( Use #pragma once instead of include guards )
- webrtc-sys/src/* headers are now used in only one place
- Avoid confusion between generated headers and our headers
- AdaptedVideoTrackSource
- Cleanup the workaround with unsupported Vec<Shared<T>>
- Put everything inside one file
This commit is contained in:
+100
-111
@@ -1,7 +1,6 @@
|
||||
use cxx::UniquePtr;
|
||||
use cxx::{SharedPtr, UniquePtr};
|
||||
use livekit_utils::enum_dispatch;
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::pin::Pin;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use webrtc_sys::media_stream as sys_ms;
|
||||
use webrtc_sys::MEDIA_TYPE_VIDEO;
|
||||
@@ -27,19 +26,19 @@ pub enum MediaStreamTrackHandle {
|
||||
}
|
||||
|
||||
impl MediaStreamTrackHandle {
|
||||
pub(crate) fn new(cxx_handle: UniquePtr<sys_ms::ffi::MediaStreamTrack>) -> Self {
|
||||
unsafe {
|
||||
if cxx_handle.kind() == MEDIA_TYPE_VIDEO {
|
||||
Self::Video(VideoTrack::new(UniquePtr::from_raw(
|
||||
sys_ms::ffi::media_to_video(cxx_handle.into_raw())
|
||||
as *mut sys_ms::ffi::VideoTrack,
|
||||
)))
|
||||
} else {
|
||||
Self::Audio(AudioTrack::new(UniquePtr::from_raw(
|
||||
sys_ms::ffi::media_to_audio(cxx_handle.into_raw())
|
||||
as *mut sys_ms::ffi::AudioTrack,
|
||||
)))
|
||||
}
|
||||
pub(crate) fn new(cxx_handle: SharedPtr<sys_ms::ffi::MediaStreamTrack>) -> Self {
|
||||
if cxx_handle.kind() == MEDIA_TYPE_VIDEO {
|
||||
Self::Video(VideoTrack::new(cxx_handle))
|
||||
} else {
|
||||
Self::Audio(AudioTrack::new(cxx_handle))
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(theomonnom): enum_dispatch with visibility support?
|
||||
pub(crate) fn cxx_handle(&self) -> SharedPtr<sys_ms::ffi::MediaStreamTrack> {
|
||||
match self {
|
||||
Self::Video(video) => video.cxx_handle(),
|
||||
Self::Audio(audio) => audio.cxx_handle(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,58 +66,123 @@ impl MediaStreamTrackTrait for MediaStreamTrackHandle {
|
||||
}
|
||||
|
||||
pub struct AudioTrack {
|
||||
cxx_handle: Mutex<UniquePtr<sys_ms::ffi::AudioTrack>>,
|
||||
cxx_handle: SharedPtr<sys_ms::ffi::MediaStreamTrack>,
|
||||
}
|
||||
|
||||
impl AudioTrack {
|
||||
pub(crate) fn new(cxx_handle: UniquePtr<sys_ms::ffi::AudioTrack>) -> Arc<Self> {
|
||||
Arc::new(Self {
|
||||
cxx_handle: Mutex::new(cxx_handle),
|
||||
})
|
||||
fn new(cxx_handle: SharedPtr<sys_ms::ffi::MediaStreamTrack>) -> Arc<Self> {
|
||||
Arc::new(Self { cxx_handle })
|
||||
}
|
||||
|
||||
pub(crate) fn cxx_handle(&self) -> SharedPtr<sys_ms::ffi::MediaStreamTrack> {
|
||||
self.cxx_handle.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct VideoTrack {
|
||||
cxx_handle: Mutex<UniquePtr<sys_ms::ffi::VideoTrack>>,
|
||||
cxx_handle: SharedPtr<sys_ms::ffi::MediaStreamTrack>,
|
||||
observer: Box<InternalVideoTrackSink>,
|
||||
|
||||
// Keep alive for c++
|
||||
native_observer: UniquePtr<sys_ms::ffi::NativeVideoFrameSink>,
|
||||
}
|
||||
|
||||
impl VideoTrack {
|
||||
fn new(cxx_handle: SharedPtr<sys_ms::ffi::MediaStreamTrack>) -> Arc<Self> {
|
||||
let mut observer = Box::new(InternalVideoTrackSink::default());
|
||||
|
||||
let mut track = unsafe {
|
||||
Self {
|
||||
cxx_handle,
|
||||
native_observer: {
|
||||
sys_ms::ffi::create_native_video_frame_sink(Box::new(
|
||||
sys_ms::VideoFrameSinkWrapper::new(&mut *observer),
|
||||
))
|
||||
},
|
||||
observer,
|
||||
}
|
||||
};
|
||||
|
||||
unsafe {
|
||||
(*track.video_handle()).add_sink(track.native_observer.pin_mut());
|
||||
}
|
||||
|
||||
Arc::new(track)
|
||||
}
|
||||
|
||||
pub(crate) fn cxx_handle(&self) -> SharedPtr<sys_ms::ffi::MediaStreamTrack> {
|
||||
self.cxx_handle.clone()
|
||||
}
|
||||
|
||||
fn video_handle(&self) -> *const sys_ms::ffi::VideoTrack {
|
||||
unsafe { sys_ms::ffi::media_to_video(&*self.cxx_handle) }
|
||||
}
|
||||
|
||||
pub fn set_should_receive(&self, should_receive: bool) {
|
||||
unsafe { (*self.video_handle()).set_should_receive(should_receive) }
|
||||
}
|
||||
|
||||
pub fn set_content_hint(&self, hint: ContentHint) {
|
||||
unsafe { (*self.video_handle()).set_content_hint(hint) }
|
||||
}
|
||||
|
||||
pub fn should_receive(&self) -> bool {
|
||||
unsafe { (*self.video_handle()).should_receive() }
|
||||
}
|
||||
|
||||
pub fn content_hint(&self) -> ContentHint {
|
||||
unsafe { (*self.video_handle()).content_hint() }
|
||||
}
|
||||
|
||||
pub fn on_frame(&self, handler: OnFrameHandler) {
|
||||
*self.observer.on_frame_handler.lock().unwrap() = Some(handler);
|
||||
}
|
||||
|
||||
pub fn on_discarded_frame(&self, handler: OnDiscardedFrameHandler) {
|
||||
*self.observer.on_discarded_frame_handler.lock().unwrap() = Some(handler);
|
||||
}
|
||||
|
||||
pub fn on_constraints_changed(&self, handler: OnConstraintsChangedHandler) {
|
||||
*self.observer.on_constraints_changed_handler.lock().unwrap() = Some(handler);
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for VideoTrack {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
(*self.video_handle()).remove_sink(self.native_observer.pin_mut());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_media_stream_track_trait {
|
||||
($x:ty, $cast:ident) => {
|
||||
($x:ty) => {
|
||||
impl MediaStreamTrackTrait for $x {
|
||||
fn kind(&self) -> String {
|
||||
unsafe { (*sys_ms::ffi::$cast(&**self.cxx_handle.lock().unwrap())).kind() }
|
||||
self.cxx_handle.kind()
|
||||
}
|
||||
|
||||
fn id(&self) -> String {
|
||||
unsafe { (*sys_ms::ffi::$cast(&**self.cxx_handle.lock().unwrap())).id() }
|
||||
self.cxx_handle.id()
|
||||
}
|
||||
|
||||
fn enabled(&self) -> bool {
|
||||
unsafe { (*sys_ms::ffi::$cast(&**self.cxx_handle.lock().unwrap())).enabled() }
|
||||
self.cxx_handle.enabled()
|
||||
}
|
||||
|
||||
fn set_enabled(&self, enabled: bool) -> bool {
|
||||
unsafe {
|
||||
let media = sys_ms::ffi::$cast(&**self.cxx_handle.lock().unwrap())
|
||||
as *mut sys_ms::ffi::MediaStreamTrack;
|
||||
|
||||
Pin::new_unchecked(&mut *media).set_enabled(enabled)
|
||||
}
|
||||
self.cxx_handle.set_enabled(enabled)
|
||||
}
|
||||
|
||||
fn state(&self) -> TrackState {
|
||||
unsafe { (*sys_ms::ffi::$cast(&**self.cxx_handle.lock().unwrap())).state() }
|
||||
self.cxx_handle.state()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_media_stream_track_trait!(VideoTrack, video_to_media);
|
||||
impl_media_stream_track_trait!(AudioTrack, audio_to_media);
|
||||
impl_media_stream_track_trait!(VideoTrack);
|
||||
impl_media_stream_track_trait!(AudioTrack);
|
||||
|
||||
pub type OnFrameHandler = Box<dyn FnMut(VideoFrame, VideoFrameBuffer) + Send + Sync>;
|
||||
pub type OnDiscardedFrameHandler = Box<dyn FnMut() + Send + Sync>;
|
||||
@@ -167,83 +231,8 @@ impl sys_ms::VideoFrameSink for InternalVideoTrackSink {
|
||||
}
|
||||
}
|
||||
|
||||
impl VideoTrack {
|
||||
fn new(cxx_handle: UniquePtr<sys_ms::ffi::VideoTrack>) -> Arc<Self> {
|
||||
let mut observer = Box::new(InternalVideoTrackSink::default());
|
||||
|
||||
let mut track = unsafe {
|
||||
Self {
|
||||
cxx_handle: Mutex::new(cxx_handle),
|
||||
native_observer: sys_ms::ffi::create_native_video_frame_sink(Box::new(
|
||||
sys_ms::VideoFrameSinkWrapper::new(&mut *observer),
|
||||
)),
|
||||
observer,
|
||||
}
|
||||
};
|
||||
|
||||
unsafe {
|
||||
track
|
||||
.cxx_handle
|
||||
.lock()
|
||||
.unwrap()
|
||||
.pin_mut()
|
||||
.add_sink(track.native_observer.pin_mut());
|
||||
}
|
||||
|
||||
Arc::new(track)
|
||||
}
|
||||
|
||||
pub fn set_should_receive(&self, should_receive: bool) {
|
||||
self.cxx_handle
|
||||
.lock()
|
||||
.unwrap()
|
||||
.pin_mut()
|
||||
.set_should_receive(should_receive)
|
||||
}
|
||||
|
||||
pub fn set_content_hint(&self, hint: ContentHint) {
|
||||
self.cxx_handle
|
||||
.lock()
|
||||
.unwrap()
|
||||
.pin_mut()
|
||||
.set_content_hint(hint)
|
||||
}
|
||||
|
||||
pub fn should_receive(&self) -> bool {
|
||||
self.cxx_handle.lock().unwrap().should_receive()
|
||||
}
|
||||
|
||||
pub fn content_hint(&self) -> ContentHint {
|
||||
self.cxx_handle.lock().unwrap().content_hint()
|
||||
}
|
||||
|
||||
pub fn on_frame(&self, handler: OnFrameHandler) {
|
||||
*self.observer.on_frame_handler.lock().unwrap() = Some(handler);
|
||||
}
|
||||
|
||||
pub fn on_discarded_frame(&self, handler: OnDiscardedFrameHandler) {
|
||||
*self.observer.on_discarded_frame_handler.lock().unwrap() = Some(handler);
|
||||
}
|
||||
|
||||
pub fn on_constraints_changed(&self, handler: OnConstraintsChangedHandler) {
|
||||
*self.observer.on_constraints_changed_handler.lock().unwrap() = Some(handler);
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for VideoTrack {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
self.cxx_handle
|
||||
.lock()
|
||||
.unwrap()
|
||||
.pin_mut()
|
||||
.remove_sink(self.native_observer.pin_mut());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MediaStream {
|
||||
cxx_handle: UniquePtr<sys_ms::ffi::MediaStream>,
|
||||
cxx_handle: SharedPtr<sys_ms::ffi::MediaStream>,
|
||||
}
|
||||
|
||||
impl Debug for MediaStream {
|
||||
@@ -255,7 +244,7 @@ impl Debug for MediaStream {
|
||||
}
|
||||
|
||||
impl MediaStream {
|
||||
pub(crate) fn new(cxx_handle: UniquePtr<sys_ms::ffi::MediaStream>) -> Self {
|
||||
pub(crate) fn new(cxx_handle: SharedPtr<sys_ms::ffi::MediaStream>) -> Self {
|
||||
Self { cxx_handle }
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user