diff --git a/.cargo/config b/.cargo/config index ac2b23f..4bf63f7 100644 --- a/.cargo/config +++ b/.cargo/config @@ -1,2 +1,8 @@ [target.x86_64-pc-windows-msvc] rustflags = ["-C", "target-feature=+crt-static"] + +[target.x86_64-apple-darwin] +rustflags = ["-C", "link-args=-ObjC"] + +[target.aarch64-apple-darwin] +rustflags = ["-C", "link-args=-ObjC"] diff --git a/webrtc-sys/build.rs b/webrtc-sys/build.rs index d0b4d69..f8e58ed 100644 --- a/webrtc-sys/build.rs +++ b/webrtc-sys/build.rs @@ -8,7 +8,7 @@ use std::path; use std::process::Command; use tar::Archive; -const WEBRTC_TAG: &str = "m104.5112.06"; +const WEBRTC_TAG: &str = "m104.5112.07"; fn download_prebuilt( target_os: &str, @@ -156,6 +156,8 @@ fn main() { builder.file("src/rtp_transceiver.cpp"); builder.file("src/rtc_error.cpp"); builder.file("src/webrtc.cpp"); + builder.file("src/video_encoder_factory.cpp"); + builder.file("src/video_decoder_factory.cpp"); for include in includes { builder.include(include); @@ -232,6 +234,8 @@ fn main() { } } + builder.file("src/objc_video_factory.mm"); + builder .flag("-stdlib=libc++") .flag("-std=c++17") diff --git a/webrtc-sys/include/livekit/objc_video_factory.h b/webrtc-sys/include/livekit/objc_video_factory.h new file mode 100644 index 0000000..2a49213 --- /dev/null +++ b/webrtc-sys/include/livekit/objc_video_factory.h @@ -0,0 +1,15 @@ +#ifndef OBJC_VIDEO_FACTORY_H +#define OBJC_VIDEO_FACTORY_H + +#include +#include "api/video_codecs/video_decoder_factory.h" +#include "api/video_codecs/video_encoder_factory.h" + +namespace livekit { + +std::unique_ptr CreateObjCVideoEncoderFactory(); +std::unique_ptr CreateObjCVideoDecoderFactory(); + +} // namespace livekit + +#endif // OBJC_VIDEO_FACTORY_H diff --git a/webrtc-sys/include/livekit/video_decoder_factory.h b/webrtc-sys/include/livekit/video_decoder_factory.h new file mode 100644 index 0000000..36e804d --- /dev/null +++ b/webrtc-sys/include/livekit/video_decoder_factory.h @@ -0,0 +1,22 @@ +#ifndef VIDEO_DECODER_FACTORY_H +#define VIDEO_DECODER_FACTORY_H + +#include "api/video_codecs/video_decoder_factory.h" +#include "api/video_codecs/video_decoder.h" + +namespace livekit { +class VideoDecoderFactory : public webrtc::VideoDecoderFactory { + public: + VideoDecoderFactory(); + + std::vector GetSupportedFormats() const override; + + std::unique_ptr CreateVideoDecoder( + const webrtc::SdpVideoFormat& format) override; + + private: + std::vector> factories_; +}; +} // namespace livekit + +#endif // VIDEO_DECODER_FACTORY_H diff --git a/webrtc-sys/include/livekit/video_encoder_factory.h b/webrtc-sys/include/livekit/video_encoder_factory.h new file mode 100644 index 0000000..f0e5d2c --- /dev/null +++ b/webrtc-sys/include/livekit/video_encoder_factory.h @@ -0,0 +1,22 @@ +#ifndef VIDEO_ENCODER_FACTORY_H +#define VIDEO_ENCODER_FACTORY_H + +#include "api/video_codecs/video_encoder_factory.h" +#include "api/video_codecs/video_encoder.h" + +namespace livekit { +class VideoEncoderFactory : public webrtc::VideoEncoderFactory { + public: + VideoEncoderFactory(); + + std::vector GetSupportedFormats() const override; + + std::unique_ptr CreateVideoEncoder( + const webrtc::SdpVideoFormat& format) override; + + private: + std::vector> factories_; +}; +} // namespace livekit + +#endif // VIDEO_ENCODER_FACTORY_H diff --git a/webrtc-sys/src/objc_video_factory.mm b/webrtc-sys/src/objc_video_factory.mm new file mode 100644 index 0000000..0dc45a7 --- /dev/null +++ b/webrtc-sys/src/objc_video_factory.mm @@ -0,0 +1,21 @@ +#include "livekit/objc_video_factory.h" + +#import +#import +#include "sdk/objc/native/api/video_decoder_factory.h" +#include "sdk/objc/native/api/video_encoder_factory.h" + +namespace livekit { + +std::unique_ptr CreateObjCVideoEncoderFactory() { + // TODO(theomonnom): Simulcast? + return webrtc::ObjCToNativeVideoEncoderFactory( + [[RTCVideoEncoderFactoryH264 alloc] init]); +} + +std::unique_ptr CreateObjCVideoDecoderFactory() { + return webrtc::ObjCToNativeVideoDecoderFactory( + [[RTCVideoDecoderFactoryH264 alloc] init]); +} + +} diff --git a/webrtc-sys/src/peer_connection_factory.cpp b/webrtc-sys/src/peer_connection_factory.cpp index d0675f8..eb8bbd2 100644 --- a/webrtc-sys/src/peer_connection_factory.cpp +++ b/webrtc-sys/src/peer_connection_factory.cpp @@ -13,6 +13,8 @@ #include "api/video_codecs/builtin_video_decoder_factory.h" #include "api/video_codecs/builtin_video_encoder_factory.h" #include "livekit/rtc_error.h" +#include "livekit/video_decoder_factory.h" +#include "livekit/video_encoder_factory.h" #include "media/engine/webrtc_media_engine.h" #include "webrtc-sys/src/peer_connection_factory.rs.h" @@ -36,8 +38,10 @@ PeerConnectionFactory::PeerConnectionFactory( cricket::MediaEngineDependencies media_deps; media_deps.task_queue_factory = dependencies.task_queue_factory.get(); - media_deps.video_encoder_factory = webrtc::CreateBuiltinVideoEncoderFactory(); - media_deps.video_decoder_factory = webrtc::CreateBuiltinVideoDecoderFactory(); + media_deps.video_encoder_factory = + std::move(std::make_unique()); + media_deps.video_decoder_factory = + std::move(std::make_unique()); media_deps.audio_encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory(); media_deps.audio_decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory(); media_deps.audio_processing = webrtc::AudioProcessingBuilder().Create(); diff --git a/webrtc-sys/src/video_decoder_factory.cpp b/webrtc-sys/src/video_decoder_factory.cpp new file mode 100644 index 0000000..d3ca4b2 --- /dev/null +++ b/webrtc-sys/src/video_decoder_factory.cpp @@ -0,0 +1,46 @@ +#include "livekit/video_decoder_factory.h" + +#include "api/video_codecs/builtin_video_decoder_factory.h" +#include "api/video_codecs/builtin_video_encoder_factory.h" +#include "api/video_codecs/sdp_video_format.h" +#include "livekit/objc_video_factory.h" +#include "media/base/media_constants.h" +#include "rtc_base/logging.h" + +namespace livekit { + +VideoDecoderFactory::VideoDecoderFactory() { + factories_.push_back(webrtc::CreateBuiltinVideoDecoderFactory()); + +#ifdef __APPLE__ + factories_.push_back(livekit::CreateObjCVideoDecoderFactory()); +#endif + + // TODO(theomonnom): Add other HW decoders here +} + +std::vector VideoDecoderFactory::GetSupportedFormats() + const { + std::vector formats; + for (const auto& factory : factories_) { + auto supported_formats = factory->GetSupportedFormats(); + formats.insert(formats.end(), supported_formats.begin(), + supported_formats.end()); + } + return formats; +} + +std::unique_ptr VideoDecoderFactory::CreateVideoDecoder( + const webrtc::SdpVideoFormat& format) { + for (const auto& factory : factories_) { + for (const auto& supported_format : factory->GetSupportedFormats()) { + if (supported_format.IsSameCodec(format)) + return factory->CreateVideoDecoder(format); + } + } + + RTC_LOG(LS_ERROR) << "No VideoDecoder found for " << format.name; + return nullptr; +} + +} // namespace livekit diff --git a/webrtc-sys/src/video_encoder_factory.cpp b/webrtc-sys/src/video_encoder_factory.cpp new file mode 100644 index 0000000..5624b67 --- /dev/null +++ b/webrtc-sys/src/video_encoder_factory.cpp @@ -0,0 +1,47 @@ +#include "livekit/video_encoder_factory.h" + +#include "api/video_codecs/builtin_video_decoder_factory.h" +#include "api/video_codecs/builtin_video_encoder_factory.h" +#include "api/video_codecs/sdp_video_format.h" +#include "api/video_codecs/video_encoder.h" +#include "livekit/objc_video_factory.h" +#include "media/base/media_constants.h" +#include "rtc_base/logging.h" + +namespace livekit { + +VideoEncoderFactory::VideoEncoderFactory() { + factories_.push_back(webrtc::CreateBuiltinVideoEncoderFactory()); + +#ifdef __APPLE__ + factories_.push_back(livekit::CreateObjCVideoEncoderFactory()); +#endif + + // TODO(theomonnom): Add other HW encoders here +} + +std::vector VideoEncoderFactory::GetSupportedFormats() + const { + std::vector formats; + for (const auto& factory : factories_) { + auto supported_formats = factory->GetSupportedFormats(); + formats.insert(formats.end(), supported_formats.begin(), + supported_formats.end()); + } + return formats; +} + +std::unique_ptr VideoEncoderFactory::CreateVideoEncoder( + const webrtc::SdpVideoFormat& format) { + for (const auto& factory : factories_) { + for (const auto& supported_format : factory->GetSupportedFormats()) { + if (supported_format.IsSameCodec(format)) + return factory->CreateVideoEncoder(format); + } + } + + RTC_LOG(LS_ERROR) << "No VideoEncoder found for " << format.name; + return nullptr; +} + +} // namespace livekit