#include "livekit/desktop_capturer.h"
#include "modules/desktop_capture/desktop_capture_options.h"
using SourceList = webrtc::DesktopCapturer::SourceList;
namespace livekit_ffi {
std::unique_ptr<DesktopCapturer> new_desktop_capturer(
DesktopCapturerOptions options) {
webrtc::DesktopCaptureOptions webrtc_options =
webrtc::DesktopCaptureOptions::CreateDefault();
#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
webrtc_options.set_allow_sck_capturer(true);
webrtc_options.set_allow_sck_system_picker(options.allow_sck_system_picker);
#endif
#ifdef _WIN64
switch (options.source_type) {
case SourceType::Screen:
webrtc_options.set_allow_wgc_screen_capturer(true);
break;
case SourceType::Window:
webrtc_options.set_allow_wgc_window_capturer(true);
webrtc_options.set_enumerate_current_process_windows(false);
break;
default:
break;
}
webrtc_options.set_allow_directx_capturer(true);
#endif
#ifdef WEBRTC_USE_PIPEWIRE
webrtc_options.set_allow_pipewire(true);
#endif
webrtc_options.set_prefer_cursor_embedded(options.include_cursor);
std::unique_ptr<webrtc::DesktopCapturer> capturer = nullptr;
switch (options.source_type) {
case SourceType::Window:
capturer = webrtc::DesktopCapturer::CreateWindowCapturer(webrtc_options);
break;
case SourceType::Screen:
capturer = webrtc::DesktopCapturer::CreateScreenCapturer(webrtc_options);
break;
case SourceType::Generic:
capturer = webrtc::DesktopCapturer::CreateGenericCapturer(webrtc_options);
break;
default:
return nullptr;
}
if (!capturer) {
return nullptr;
}
return std::make_unique<DesktopCapturer>(std::move(capturer));
}
void DesktopCapturer::start(
rust::Box<DesktopCapturerCallbackWrapper> callback) {
this->callback = std::move(callback);
capturer->Start(this);
}
void DesktopCapturer::OnCaptureResult(
webrtc::DesktopCapturer::Result result,
std::unique_ptr<webrtc::DesktopFrame> frame) {
CaptureResult ret_result = CaptureResult::ErrorPermanent;
switch (result) {
case webrtc::DesktopCapturer::Result::SUCCESS:
ret_result = CaptureResult::Success;
break;
case webrtc::DesktopCapturer::Result::ERROR_PERMANENT:
ret_result = CaptureResult::ErrorPermanent;
break;
case webrtc::DesktopCapturer::Result::ERROR_TEMPORARY:
ret_result = CaptureResult::ErrorTemporary;
break;
default:
break;
}
if (callback) {
(*callback)->on_capture_result(
ret_result, std::make_unique<DesktopFrame>(std::move(frame)));
}
}
rust::Vec<Source> DesktopCapturer::get_source_list() const {
SourceList list{};
bool res = capturer->GetSourceList(&list);
rust::Vec<Source> source_list{};
if (res) {
for (auto& source : list) {
source_list.push_back(Source{static_cast<uint64_t>(source.id),
source.title, source.display_id});
}
}
return source_list;
}
}