From 85c4f122585172f2aee5d993247596e3e1e880e1 Mon Sep 17 00:00:00 2001 From: Gerasim Troeglazov <3dEyes@gmail.com> Date: Thu, 1 Aug 2024 20:17:51 +1000 Subject: Add Haiku support diff --git a/CMakeLists.txt b/CMakeLists.txt index a36752b..28dd4a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1453,6 +1453,9 @@ PRIVATE modules/video_capture/linux/video_capture_pipewire.h modules/video_capture/linux/video_capture_v4l2.cc modules/video_capture/linux/video_capture_v4l2.h + modules/video_capture/haiku/device_info_haiku.cc + modules/video_capture/haiku/video_capture_haiku.cc + modules/video_capture/haiku/video_consumer.cc modules/video_capture/windows/device_info_ds.cc modules/video_capture/windows/device_info_ds.h modules/video_capture/windows/help_functions_ds.cc @@ -2212,6 +2215,7 @@ PRIVATE modules/desktop_capture/mouse_cursor.h modules/desktop_capture/mouse_cursor_monitor.h modules/desktop_capture/mouse_cursor_monitor_linux.cc + modules/desktop_capture/mouse_cursor_monitor_haiku.cc modules/desktop_capture/mouse_cursor_monitor_mac.mm modules/desktop_capture/mouse_cursor_monitor_win.cc modules/desktop_capture/resolution_tracker.cc @@ -2223,8 +2227,10 @@ PRIVATE modules/desktop_capture/screen_capturer_helper.h modules/desktop_capture/screen_capturer_darwin.mm modules/desktop_capture/screen_capturer_linux.cc + modules/desktop_capture/screen_capturer_haiku.cc modules/desktop_capture/screen_capturer_win.cc modules/desktop_capture/window_capturer_linux.cc + modules/desktop_capture/window_capturer_haiku.cc modules/desktop_capture/window_capturer_mac.mm modules/desktop_capture/window_capturer_win.cc modules/desktop_capture/window_finder.cc @@ -2239,6 +2245,10 @@ PRIVATE modules/desktop_capture/screen_capturer_null.cc modules/desktop_capture/window_capturer_null.cc + # haiku specific + modules/desktop_capture/haiku/screen_capturer_haiku.cc + modules/desktop_capture/haiku/screen_capturer_haiku.h + # linux specific modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc modules/desktop_capture/linux/wayland/base_capturer_pipewire.h diff --git a/cmake/libwebrtcbuild.cmake b/cmake/libwebrtcbuild.cmake index 4838e03..c15cef1 100644 --- a/cmake/libwebrtcbuild.cmake +++ b/cmake/libwebrtcbuild.cmake @@ -64,6 +64,12 @@ if (WIN32) WEBRTC_WIN RTC_ENABLE_WIN_WGC ) +elseif (HAIKU) + target_compile_definitions(libwebrtcbuild + INTERFACE + WEBRTC_POSIX + WEBRTC_HAIKU + ) else() target_compile_definitions(libwebrtcbuild INTERFACE diff --git a/cmake/nice_target_sources.cmake b/cmake/nice_target_sources.cmake index cfc6aeb..699d0e6 100644 --- a/cmake/nice_target_sources.cmake +++ b/cmake/nice_target_sources.cmake @@ -15,6 +15,7 @@ function(nice_target_sources target_name src_loc) set(not_win_sources "") set(not_mac_sources "") set(not_linux_sources "") + set(not_haiku_sources "") foreach (entry ${list}) if (${entry} STREQUAL "PRIVATE" OR ${entry} STREQUAL "PUBLIC" OR ${entry} STREQUAL "INTERFACE") set(writing_now ${entry}) @@ -23,12 +24,19 @@ function(nice_target_sources target_name src_loc) if (${entry} MATCHES "(^|/)win/" OR ${entry} MATCHES "(^|/)winrc/" OR ${entry} MATCHES "(^|/)windows/" OR ${entry} MATCHES "[_\\/]win\\.") list(APPEND not_mac_sources ${full_name}) list(APPEND not_linux_sources ${full_name}) + list(APPEND not_haiku_sources ${full_name}) elseif (${entry} MATCHES "(^|/)mac/" OR ${entry} MATCHES "(^|/)darwin/" OR ${entry} MATCHES "(^|/)osx/" OR ${entry} MATCHES "[_\\/]mac\\." OR ${entry} MATCHES "[_\\/]darwin\\." OR ${entry} MATCHES "[_\\/]osx\\.") list(APPEND not_win_sources ${full_name}) list(APPEND not_linux_sources ${full_name}) + list(APPEND not_haiku_sources ${full_name}) elseif (${entry} MATCHES "(^|/)linux/" OR ${entry} MATCHES "[_\\/]linux\\.") list(APPEND not_win_sources ${full_name}) list(APPEND not_mac_sources ${full_name}) + list(APPEND not_haiku_sources ${full_name}) + elseif (${entry} MATCHES "(^|/)haiku/" OR ${entry} MATCHES "[_\\/]haiku\\.") + list(APPEND not_win_sources ${full_name}) + list(APPEND not_mac_sources ${full_name}) + list(APPEND not_linux_sources ${full_name}) elseif (${entry} MATCHES "(^|/)posix/" OR ${entry} MATCHES "[_\\/]posix\\.") list(APPEND not_win_sources ${full_name}) endif() @@ -64,6 +72,9 @@ function(nice_target_sources target_name src_loc) elseif (APPLE) set_source_files_properties(${not_mac_sources} PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties(${not_mac_sources} PROPERTIES SKIP_AUTOGEN TRUE) + elseif (HAIKU) + set_source_files_properties(${not_haiku_sources} PROPERTIES HEADER_FILE_ONLY TRUE) + set_source_files_properties(${not_haiku_sources} PROPERTIES SKIP_AUTOGEN TRUE) else() set_source_files_properties(${not_linux_sources} PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties(${not_linux_sources} PROPERTIES SKIP_AUTOGEN TRUE) diff --git a/src/api/task_queue/BUILD.gn b/src/api/task_queue/BUILD.gn index 1b9425d..ff93aea 100644 --- a/src/api/task_queue/BUILD.gn +++ b/src/api/task_queue/BUILD.gn @@ -95,7 +95,7 @@ rtc_library("default_task_queue_factory") { "../../rtc_base/memory:always_valid_pointer", ] - if (rtc_enable_libevent) { + if (rtc_enable_libevent && !is_haiku) { if (is_android) { sources += [ "default_task_queue_factory_stdlib_or_libevent_experiment.cc" ] diff --git a/src/modules/audio_coding/neteq/reorder_optimizer.cc b/src/modules/audio_coding/neteq/reorder_optimizer.cc index f6e073f..ed71751 100644 --- a/src/modules/audio_coding/neteq/reorder_optimizer.cc +++ b/src/modules/audio_coding/neteq/reorder_optimizer.cc @@ -12,6 +12,7 @@ #include #include +#include #include namespace webrtc { diff --git a/src/modules/desktop_capture/haiku/screen_capturer_haiku.cc b/src/modules/desktop_capture/haiku/screen_capturer_haiku.cc new file mode 100644 index 0000000..b6f4d24 --- /dev/null +++ b/src/modules/desktop_capture/haiku/screen_capturer_haiku.cc @@ -0,0 +1,91 @@ +/* + * Copyright 2021 Gerasim Troeglazov + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "modules/desktop_capture/haiku/screen_capturer_haiku.h" + +#include +#include + +#include +#include + +#include "modules/desktop_capture/desktop_capture_options.h" +#include "modules/desktop_capture/desktop_capturer.h" +#include "modules/desktop_capture/desktop_frame.h" +#include "modules/desktop_capture/desktop_geometry.h" +#include "modules/desktop_capture/screen_capture_frame_queue.h" +#include "modules/desktop_capture/screen_capturer_helper.h" +#include "modules/desktop_capture/shared_desktop_frame.h" +#include "rtc_base/checks.h" +#include "rtc_base/logging.h" +#include "rtc_base/sanitizer.h" +#include "rtc_base/time_utils.h" +#include "rtc_base/trace_event.h" + +namespace webrtc { + +ScreenCapturerHaiku::ScreenCapturerHaiku() { + screen_ = new BScreen(B_MAIN_SCREEN_ID); + screen_->GetBitmap(&bitmap_); +} + +ScreenCapturerHaiku::~ScreenCapturerHaiku() { + delete screen_; + delete bitmap_; +} + +bool ScreenCapturerHaiku::Init(const DesktopCaptureOptions& options) { + options_ = options; + return true; +} + +void ScreenCapturerHaiku::Start(Callback* callback) { + RTC_DCHECK(!callback_); + RTC_DCHECK(callback); + callback_ = callback; + lastShot_ = system_time(); +} + +void ScreenCapturerHaiku::CaptureFrame() { + int64_t capture_start_time_nanos = rtc::TimeNanos(); + bigtime_t now_ = system_time(); + if (now_ - lastShot_ > 1000000) { + screen_->ReadBitmap(bitmap_); + lastShot_ = now_; + } + DesktopRect r = DesktopRect::MakeXYWH(0, 0, bitmap_->Bounds().Width() + 1, bitmap_->Bounds().Height() + 1); + std::unique_ptr frame(new BasicDesktopFrame(r.size())); + frame->CopyPixelsFrom((const uint8_t*)bitmap_->Bits(), bitmap_->BytesPerRow(), r); + frame->set_capture_time_ms((rtc::TimeNanos() - capture_start_time_nanos) / rtc::kNumNanosecsPerMillisec); + callback_->OnCaptureResult(Result::SUCCESS, std::move(frame)); +} + +bool ScreenCapturerHaiku::GetSourceList(SourceList* sources) { + sources->push_back({kFullDesktopScreenId, "Active Desktop"}); + return true; +} + +bool ScreenCapturerHaiku::SelectSource(SourceId id) { + return id == kFullDesktopScreenId; +} + + +// static +std::unique_ptr ScreenCapturerHaiku::CreateRawScreenCapturer( + const DesktopCaptureOptions& options) { + std::unique_ptr capturer(new ScreenCapturerHaiku()); + if (!capturer.get()->Init(options)) { + return nullptr; + } + + return std::move(capturer); +} + +} // namespace webrtc diff --git a/src/modules/desktop_capture/haiku/screen_capturer_haiku.h b/src/modules/desktop_capture/haiku/screen_capturer_haiku.h new file mode 100644 index 0000000..b24160e --- /dev/null +++ b/src/modules/desktop_capture/haiku/screen_capturer_haiku.h @@ -0,0 +1,55 @@ +/* + * Copyright 2021 Gerasim Troeglazov + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef MODULES_DESKTOP_CAPTURE_HAIKU_SCREEN_CAPTURER_HAIKU_H_ +#define MODULES_DESKTOP_CAPTURE_HAIKU_SCREEN_CAPTURER_HAIKU_H_ + +#include + +#include "modules/desktop_capture/desktop_capture_options.h" +#include "modules/desktop_capture/desktop_capturer.h" +#include "modules/desktop_capture/desktop_frame.h" +#include "modules/desktop_capture/desktop_region.h" +#include "modules/desktop_capture/screen_capture_frame_queue.h" +#include "modules/desktop_capture/screen_capturer_helper.h" +#include "modules/desktop_capture/shared_desktop_frame.h" + +#include +#include + +namespace webrtc { + +class ScreenCapturerHaiku : public DesktopCapturer { + public: + ScreenCapturerHaiku(); + ~ScreenCapturerHaiku() override; + + static std::unique_ptr CreateRawScreenCapturer( + const DesktopCaptureOptions& options); + + bool Init(const DesktopCaptureOptions& options); + + void Start(Callback* delegate) override; + void CaptureFrame() override; + bool GetSourceList(SourceList* sources) override; + bool SelectSource(SourceId id) override; + + private: + BScreen* screen_; + BBitmap* bitmap_; + bigtime_t lastShot_; + + DesktopCaptureOptions options_; + Callback* callback_ = nullptr; +}; + +} + +#endif // MODULES_DESKTOP_CAPTURE_HAIKU_SCREEN_CAPTURER_HAIKU_H_ diff --git a/src/modules/desktop_capture/mouse_cursor_monitor_haiku.cc b/src/modules/desktop_capture/mouse_cursor_monitor_haiku.cc new file mode 100644 index 0000000..8ea2aa2 --- /dev/null +++ b/src/modules/desktop_capture/mouse_cursor_monitor_haiku.cc @@ -0,0 +1,39 @@ +/* + * Copyright 2018 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include + +#include "modules/desktop_capture/desktop_capture_types.h" +#include "modules/desktop_capture/mouse_cursor_monitor.h" +//#include "modules/desktop_capture/haiku/mouse_cursor_monitor.h" + +namespace webrtc { + +// static +MouseCursorMonitor* MouseCursorMonitor::CreateForWindow( + const DesktopCaptureOptions& options, + WindowId window) { + return nullptr; +} + +// static +MouseCursorMonitor* MouseCursorMonitor::CreateForScreen( + const DesktopCaptureOptions& options, + ScreenId screen) { + return nullptr; +} + +// static +std::unique_ptr MouseCursorMonitor::Create( + const DesktopCaptureOptions& options) { + return nullptr; +} + +} // namespace webrtc diff --git a/src/modules/desktop_capture/screen_capturer_haiku.cc b/src/modules/desktop_capture/screen_capturer_haiku.cc new file mode 100644 index 0000000..63ceecc --- /dev/null +++ b/src/modules/desktop_capture/screen_capturer_haiku.cc @@ -0,0 +1,26 @@ +/* + * Copyright 2021 Gerasim Troeglazov + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include + +#include "modules/desktop_capture/desktop_capture_options.h" +#include "modules/desktop_capture/desktop_capturer.h" + +#include "modules/desktop_capture/haiku/screen_capturer_haiku.h" + +namespace webrtc { + +// static +std::unique_ptr DesktopCapturer::CreateRawScreenCapturer( + const DesktopCaptureOptions& options) { + return ScreenCapturerHaiku::CreateRawScreenCapturer(options); +} + +} // namespace webrtc diff --git a/src/modules/desktop_capture/window_capturer_haiku.cc b/src/modules/desktop_capture/window_capturer_haiku.cc new file mode 100644 index 0000000..a89b4a1 --- /dev/null +++ b/src/modules/desktop_capture/window_capturer_haiku.cc @@ -0,0 +1,64 @@ +/* + * Copyright 2021 Gerasim Troeglazov + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "modules/desktop_capture/desktop_capturer.h" +#include "modules/desktop_capture/desktop_frame.h" + +#include + +namespace webrtc { + +namespace { + +class WindowCapturerHaiku : public DesktopCapturer { + public: + WindowCapturerHaiku(); + ~WindowCapturerHaiku() override; + + void Start(Callback* callback) override; + void CaptureFrame() override; + bool GetSourceList(SourceList* sources) override; + bool SelectSource(SourceId id) override; + + private: + Callback* callback_ = nullptr; +}; + +WindowCapturerHaiku::WindowCapturerHaiku() {} +WindowCapturerHaiku::~WindowCapturerHaiku() {} + +bool WindowCapturerHaiku::GetSourceList(SourceList* sources) { + return false; +} + +bool WindowCapturerHaiku::SelectSource(SourceId id) { + return false; +} + +void WindowCapturerHaiku::Start(Callback* callback) { + assert(!callback_); + assert(callback); + + callback_ = callback; +} + +void WindowCapturerHaiku::CaptureFrame() { + callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); +} + +} // namespace + +// static +std::unique_ptr DesktopCapturer::CreateRawWindowCapturer( + const DesktopCaptureOptions& options) { + return std::unique_ptr(new WindowCapturerHaiku()); +} + +} // namespace webrtc diff --git a/src/modules/video_capture/haiku/device_info_haiku.cc b/src/modules/video_capture/haiku/device_info_haiku.cc new file mode 100644 index 0000000..aeddaef --- /dev/null +++ b/src/modules/video_capture/haiku/device_info_haiku.cc @@ -0,0 +1,150 @@ +/* + * Copyright 2021 Gerasim Troeglazov + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "modules/video_capture/haiku/device_info_haiku.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "modules/video_capture/video_capture.h" +#include "modules/video_capture/video_capture_defines.h" +#include "modules/video_capture/video_capture_impl.h" +#include "rtc_base/logging.h" + +namespace webrtc { +namespace videocapturemodule { +VideoCaptureModule::DeviceInfo* VideoCaptureImpl::CreateDeviceInfo() { + return new videocapturemodule::DeviceInfoHaiku(); +} + +DeviceInfoHaiku::DeviceInfoHaiku() : DeviceInfoImpl() {} + +int32_t DeviceInfoHaiku::Init() { + return 0; +} + +DeviceInfoHaiku::~DeviceInfoHaiku() {} + +uint32_t DeviceInfoHaiku::NumberOfDevices() { + status_t err = B_OK; + + int32_t countDevices = 0; + + dormant_node_info dni[30]; + int32 ioCount = 30; + media_format out; + out.type = B_MEDIA_RAW_VIDEO; + err = BMediaRoster::Roster()->GetDormantNodes(dni, &ioCount, 0, &out, 0, B_BUFFER_PRODUCER); + if (err < B_OK) + return countDevices; + + for (int ix=0; ixGetInstancesFor( + dni[ix].addon, dni[ix].flavor_id, &running)) && (running > -1)) { + media_node node; + BMediaRoster::CurrentRoster()->GetNodeFor(running, &node); + int32 count = 1; + media_output videoOutput; + BMediaRoster::CurrentRoster()->GetAllOutputsFor(node, &videoOutput, 1, &count); + if (count > 0) + countDevices++; + BMediaRoster::CurrentRoster()->ReleaseNode(node); + } + } + + return countDevices; +} + +int32_t DeviceInfoHaiku::GetDeviceName(uint32_t deviceNumber, + char* deviceNameUTF8, + uint32_t deviceNameLength, + char* deviceUniqueIdUTF8, + uint32_t deviceUniqueIdUTF8Length, + char* productUniqueIdUTF8, + uint32_t productUniqueIdUTF8Length) { + if (deviceNumber >= NumberOfDevices()) + return -1; + + status_t err = B_OK; + + int32_t countDevices = 0; + + media_output videoOutput; + + dormant_node_info dni[30]; + int32 ioCount = 30; + media_format out; + out.type = B_MEDIA_RAW_VIDEO; + err = BMediaRoster::Roster()->GetDormantNodes(dni, &ioCount, 0, &out, 0, B_BUFFER_PRODUCER); + if (err < B_OK) + return countDevices; + + err = B_ERROR; + + for (int ix=0; ixGetInstancesFor( + dni[ix].addon, dni[ix].flavor_id, &running)) && (running > -1)) { + media_node node; + BMediaRoster::CurrentRoster()->GetNodeFor(running, &node); + int32 count = 1; + BMediaRoster::CurrentRoster()->GetAllOutputsFor(node, &videoOutput, 1, &count); + BMediaRoster::CurrentRoster()->ReleaseNode(node); + if (count > 0) { + if (countDevices == deviceNumber) { + if (deviceNameLength > strlen(videoOutput.name)) { + strncpy(deviceNameUTF8, videoOutput.name, deviceNameLength); + strncpy(deviceUniqueIdUTF8, videoOutput.name, deviceUniqueIdUTF8Length); + err = B_OK; + } else + err = B_ERROR; + break; + } + countDevices++; + } + BMediaRoster::CurrentRoster()->ReleaseNode(node); + } + } + return err == B_OK ? 0 : -1; +} + +int32_t DeviceInfoHaiku::CreateCapabilityMap(const char* deviceUniqueIdUTF8) { + _captureCapabilities.clear(); + + VideoCaptureCapability cap; + cap.width = 640; + cap.height = 480; + cap.videoType = VideoType::kARGB; + cap.maxFPS = 30; + + _captureCapabilities.push_back(cap); + + return _captureCapabilities.size(); +} + +int32_t DeviceInfoHaiku::DisplayCaptureSettingsDialogBox( + const char* deviceUniqueIdUTF8, + const char* dialogTitleUTF8, + void* parentWindow, + uint32_t positionX, + uint32_t positionY) { + return -1; +} + +} // namespace videocapturemodule +} // namespace webrtc diff --git a/src/modules/video_capture/haiku/device_info_haiku.h b/src/modules/video_capture/haiku/device_info_haiku.h new file mode 100644 index 0000000..b5ffe94 --- /dev/null +++ b/src/modules/video_capture/haiku/device_info_haiku.h @@ -0,0 +1,43 @@ +/* + * Copyright 2021 Gerasim Troeglazov + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef MODULES_VIDEO_CAPTURE_MAIN_SOURCE_HAIKU_DEVICE_INFO_HAIKU_H_ +#define MODULES_VIDEO_CAPTURE_MAIN_SOURCE_HAIKU_DEVICE_INFO_HAIKU_H_ + +#include +#include + +#include "modules/video_capture/device_info_impl.h" + +namespace webrtc { +namespace videocapturemodule { +class DeviceInfoHaiku : public DeviceInfoImpl { + public: + DeviceInfoHaiku(); + ~DeviceInfoHaiku() override; + uint32_t NumberOfDevices() override; + int32_t GetDeviceName(uint32_t deviceNumber, + char* deviceNameUTF8, + uint32_t deviceNameLength, + char* deviceUniqueIdUTF8, + uint32_t deviceUniqueIdUTF8Length, + char* productUniqueIdUTF8 = 0, + uint32_t productUniqueIdUTF8Length = 0) override; + int32_t CreateCapabilityMap(const char* deviceUniqueIdUTF8) override; + int32_t DisplayCaptureSettingsDialogBox(const char*, + const char*, + void*, + uint32_t, + uint32_t) override; + int32_t Init() override; +}; +} // namespace videocapturemodule +} // namespace webrtc +#endif // MODULES_VIDEO_CAPTURE_MAIN_SOURCE_HAIKU_DEVICE_INFO_HAIKU_H_ diff --git a/src/modules/video_capture/haiku/video_capture_haiku.cc b/src/modules/video_capture/haiku/video_capture_haiku.cc new file mode 100644 index 0000000..86d8d20 --- /dev/null +++ b/src/modules/video_capture/haiku/video_capture_haiku.cc @@ -0,0 +1,201 @@ +/* + * Copyright 2021 Gerasim Troeglazov + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "modules/video_capture/haiku/video_capture_haiku.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "api/scoped_refptr.h" +#include "media/base/video_common.h" +#include "modules/video_capture/video_capture.h" +#include "rtc_base/logging.h" +#include "rtc_base/ref_counted_object.h" + +namespace webrtc { +namespace videocapturemodule { +rtc::scoped_refptr VideoCaptureImpl::Create( + const char* deviceUniqueId) { + rtc::scoped_refptr implementation( + new rtc::RefCountedObject()); + + if (implementation->Init(deviceUniqueId) != 0) + return nullptr; + + return implementation; +} + +VideoCaptureModuleHaiku::VideoCaptureModuleHaiku() + : VideoCaptureImpl(), + _currentWidth(-1), + _currentHeight(-1), + _currentFrameRate(-1), + _captureStarted(false), + _captureVideoType(VideoType::kARGB) {} + +int32_t VideoCaptureModuleHaiku::Init(const char* deviceUniqueIdUTF8) { + int len = strlen((const char*)deviceUniqueIdUTF8); + _deviceUniqueId = new (std::nothrow) char[len + 1]; + if (_deviceUniqueId) { + memcpy(_deviceUniqueId, deviceUniqueIdUTF8, len + 1); + } + + return 0; +} + +VideoCaptureModuleHaiku::~VideoCaptureModuleHaiku() { + StopCapture(); +} + +int32_t VideoCaptureModuleHaiku::StartCapture( + const VideoCaptureCapability& capability) { + if (_captureStarted) { + if (capability.width == _currentWidth && + capability.height == _currentHeight && + _captureVideoType == capability.videoType) { + return 0; + } else { + StopCapture(); + } + } + + _currentWidth = 640; + _currentHeight = 480; + _currentFrameRate = 30; + + status_t fStatus; + fMediaRoster = BMediaRoster::Roster(&fStatus); + if (fStatus != B_OK) + return -1; + + media_node fTimeSource; + fStatus = fMediaRoster->GetTimeSource(&fTimeSource); + if (fStatus != B_OK) + return -1; + + fVideoConsumer = new VideoConsumer("Telegram", NULL, 0); + fVideoConsumer->SetVideoCapture(this); + + dormant_node_info dni[30]; + int32 ioCount = 30; + media_format out; + out.type = B_MEDIA_RAW_VIDEO; + fStatus = BMediaRoster::Roster()->GetDormantNodes(dni, &ioCount, 0, &out, 0, B_BUFFER_PRODUCER); + if (fStatus < B_OK) + return -1; + + fStatus = B_ERROR; + for (int ix=0; ixGetInstancesFor( + dni[ix].addon, dni[ix].flavor_id, &running)) && (running > -1)) { + BMediaRoster::CurrentRoster()->GetNodeFor(running, &fProducerNode); + int32 count = 1; + BMediaRoster::CurrentRoster()->GetFreeOutputsFor( + fProducerNode, &videoOutput, 1, &count, B_MEDIA_RAW_VIDEO); + if (count > 0) { + if (strcmp(videoOutput.name, _deviceUniqueId) == 0) { + fStatus = B_OK; + break; + } + } + BMediaRoster::CurrentRoster()->ReleaseNode(fProducerNode); + } + } + if (fStatus != B_OK) + return -1; + + fStatus = fMediaRoster->RegisterNode(fVideoConsumer); + if (fStatus != B_OK) + return -1; + fConsumerNode = fVideoConsumer->Node(); + + int32 count = 1; + fStatus = fMediaRoster->GetFreeInputsFor(fConsumerNode, &videoInput, 1, &count, B_MEDIA_RAW_VIDEO); + if (fStatus != B_OK || count < 1) + return -1; + + // connect the nodes + media_format format; + format.type = B_MEDIA_RAW_VIDEO; + media_raw_video_format videoFormat = { + 29.97f, 1, 0, + 639, + B_VIDEO_TOP_LEFT_RIGHT, 1, 1, + { + B_RGB32, + (uint32)(640), + (uint32)(480), + 0, 0, 0 + } + }; + format.u.raw_video = videoFormat; + + fStatus = fMediaRoster->Connect(videoOutput.source, videoInput.destination, + &format, &videoOutput, &videoInput); + + if (fStatus != B_OK) + return -1; + + timeSource = fMediaRoster->MakeTimeSourceFor(fTimeSource); + bigtime_t real = BTimeSource::RealTime(); + bigtime_t perf = timeSource->PerformanceTimeFor(real) + 3000000; + + fStatus = fMediaRoster->StartNode(fConsumerNode, perf); + if (fStatus != B_OK) + return -1; + + fStatus = fMediaRoster->StopNode(fProducerNode, perf, true); + fStatus = fMediaRoster->StartNode(fProducerNode, perf); + if (fStatus != B_OK) + return -1; + + _captureStarted = true; + return 0; +} + +int32_t VideoCaptureModuleHaiku::StopCapture() { + if (_captureStarted) { + fMediaRoster->StopNode(fProducerNode, BTimeSource::RealTime(), true); + fMediaRoster->Disconnect(fProducerNode.node, videoOutput.source, + fConsumerNode.node, videoInput.destination); + fMediaRoster->UnregisterNode(fVideoConsumer); + delete fVideoConsumer; + _captureStarted = false; + } + + return 0; +} + +bool VideoCaptureModuleHaiku::CaptureStarted() { + return _captureStarted; +} + +int32_t VideoCaptureModuleHaiku::CaptureSettings( + VideoCaptureCapability& settings) { + settings.width = _currentWidth; + settings.height = _currentHeight; + settings.maxFPS = _currentFrameRate; + settings.videoType = _captureVideoType; + + return 0; +} +} // namespace videocapturemodule +} // namespace webrtc diff --git a/src/modules/video_capture/haiku/video_capture_haiku.h b/src/modules/video_capture/haiku/video_capture_haiku.h new file mode 100644 index 0000000..5bce5bd --- /dev/null +++ b/src/modules/video_capture/haiku/video_capture_haiku.h @@ -0,0 +1,58 @@ +/* + * Copyright 2021 Gerasim Troeglazov + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef MODULES_VIDEO_CAPTURE_MAIN_SOURCE_HAIKU_VIDEO_CAPTURE_HAIKU_H_ +#define MODULES_VIDEO_CAPTURE_MAIN_SOURCE_HAIKU_VIDEO_CAPTURE_HAIKU_H_ + +#include +#include + +#include + +#include + +#include "modules/video_capture/video_capture_defines.h" +#include "modules/video_capture/video_capture_impl.h" +#include "rtc_base/platform_thread.h" +#include "rtc_base/synchronization/mutex.h" + +#include "video_consumer.h" + +namespace webrtc { +namespace videocapturemodule { +class VideoCaptureModuleHaiku : public VideoCaptureImpl { + public: + VideoCaptureModuleHaiku(); + ~VideoCaptureModuleHaiku() override; + int32_t Init(const char* deviceUniqueId); + int32_t StartCapture(const VideoCaptureCapability& capability) override; + int32_t StopCapture() override; + bool CaptureStarted() override; + int32_t CaptureSettings(VideoCaptureCapability& settings) override; + + private: + BMediaRoster *fMediaRoster; + VideoConsumer *fVideoConsumer; + BTimeSource* timeSource; + media_node fProducerNode; + media_node fConsumerNode; + media_input videoInput; + media_output videoOutput; + + int32_t _currentWidth; + int32_t _currentHeight; + int32_t _currentFrameRate; + bool _captureStarted; + VideoType _captureVideoType; +}; +} // namespace videocapturemodule +} // namespace webrtc + +#endif // MODULES_VIDEO_CAPTURE_MAIN_SOURCE_HAIKU_VIDEO_CAPTURE_HAIKU_H_ diff --git a/src/modules/video_capture/haiku/video_consumer.cc b/src/modules/video_capture/haiku/video_consumer.cc new file mode 100644 index 0000000..556d846 --- /dev/null +++ b/src/modules/video_capture/haiku/video_consumer.cc @@ -0,0 +1,475 @@ +/* + * Copyright 2021 Gerasim Troeglazov + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "video_consumer.h" + +namespace webrtc { +namespace videocapturemodule { + +VideoConsumer::VideoConsumer(const char* name, BMediaAddOn* addon, + const uint32 internal_id) + : BMediaNode(name), + BMediaEventLooper(), + BBufferConsumer(B_MEDIA_RAW_VIDEO), + fInternalID(internal_id), + fAddOn(addon), + fConnectionActive(false), + fMyLatency(3000), + fOurBuffers(false), + fBuffers(NULL), + fLastBufferIndex(-1), + fVideoCapture(NULL) +{ + AddNodeKind(B_PHYSICAL_OUTPUT); + SetEventLatency(0); + + for (uint32 i = 0; i < kBufferCount; i++) { + fBitmap[i] = NULL; + fBufferMap[i] = NULL; + } + + SetPriority(B_DISPLAY_PRIORITY); +} + + +VideoConsumer::~VideoConsumer() +{ + Quit(); + DeleteBuffers(); +} + + +void +VideoConsumer::SetVideoCapture(VideoCaptureImpl *impl) +{ + fVideoCapture = impl; +} + + +BMediaAddOn* +VideoConsumer::AddOn(int32* cookie) const +{ + *cookie = fInternalID; + return fAddOn; +} + + +void +VideoConsumer::NodeRegistered() +{ + fIn.destination.port = ControlPort(); + fIn.destination.id = 0; + fIn.source = media_source::null; + fIn.format.type = B_MEDIA_RAW_VIDEO; + // wild cards yet + fIn.format.u.raw_video = media_raw_video_format::wildcard; + fIn.format.u.raw_video.interlace = 1; + fIn.format.u.raw_video.display.format = B_NO_COLOR_SPACE; + fIn.format.u.raw_video.display.bytes_per_row = 0; + fIn.format.u.raw_video.display.line_width = 0; + fIn.format.u.raw_video.display.line_count = 0; + + Run(); +} + + +status_t +VideoConsumer::RequestCompleted(const media_request_info& info) +{ + switch(info.what) { + case media_request_info::B_SET_OUTPUT_BUFFERS_FOR: + if (info.status != B_OK) + fprintf(stderr, "VideoConsumer::RequestCompleted: Not using our buffers!\n"); + break; + default: + break; + } + return B_OK; +} + + +status_t +VideoConsumer::HandleMessage(int32 message, const void* data, size_t size) +{ + return B_OK; +} + + +void +VideoConsumer::BufferReceived(BBuffer* buffer) +{ + if (RunState() == B_STOPPED) { + buffer->Recycle(); + return; + } + media_timed_event event(buffer->Header()->start_time, + BTimedEventQueue::B_HANDLE_BUFFER, buffer, + BTimedEventQueue::B_RECYCLE_BUFFER); + EventQueue()->AddEvent(event); +} + + +void +VideoConsumer::ProducerDataStatus(const media_destination& forWhom, + int32 status, bigtime_t atMediaTime) +{ + if (forWhom != fIn.destination) + return; +} + + +status_t +VideoConsumer::CreateBuffers(const media_format& format) +{ + DeleteBuffers(); + + status_t status = B_OK; + + uint32 width = format.u.raw_video.display.line_width; + uint32 height = format.u.raw_video.display.line_count; + color_space colorSpace = format.u.raw_video.display.format; + + fBuffers = new BBufferGroup(); + status = fBuffers->InitCheck(); + if (B_OK != status) + return status; + + BRect bounds(0, 0, width - 1, height - 1); + for (uint32 i = 0; i < kBufferCount; i++) { + uint32 bitmapFlags = 0; + bitmapFlags = B_BITMAP_IS_LOCKED; + + fBitmap[i] = new BBitmap(bounds, bitmapFlags, colorSpace); + status = fBitmap[i]->InitCheck(); + if (status >= B_OK) { + buffer_clone_info info; + + uint8* bits = (uint8*)fBitmap[i]->Bits(); + info.area = area_for(bits); + area_info bitmapAreaInfo; + status = get_area_info(info.area, &bitmapAreaInfo); + if (status != B_OK) { + fprintf(stderr, "VideoConsumer::CreateBuffers() - " + "get_area_info(): %s\n", strerror(status)); + return status; + } + + info.offset = bits - (uint8*)bitmapAreaInfo.address; + info.size = (size_t)fBitmap[i]->BitsLength(); + info.flags = 0; + info.buffer = 0; + + BBuffer* buffer = NULL; + if ((status = fBuffers->AddBuffer(info, &buffer)) != B_OK) { + fprintf(stderr, "VideoConsumer::CreateBuffers - ERROR ADDING BUFFER " + "TO GROUP (%" B_PRId32 "): %s\n", i, strerror(status)); + return status; + } + fBufferMap[i] = buffer; + } else { + fprintf(stderr, "VideoConsumer::CreateBuffers - ERROR CREATING VIDEO RING " + "BUFFER (Index %" B_PRId32 " Width %" B_PRId32 " Height %" + B_PRId32 " Colorspace %d: %s\n", i, width, height, colorSpace, + strerror(status)); + return status; + } + } + + return status; +} + + +void +VideoConsumer::DeleteBuffers() +{ + if (fBuffers) { + fTargetLock.Lock(); + if (fLastBufferIndex >= 0) { + fLastBufferIndex = -1; + } + fTargetLock.Unlock(); + + delete fBuffers; + fBuffers = NULL; + + for (uint32 i = 0; i < kBufferCount; i++) { + snooze(20000); + delete fBitmap[i]; + fBitmap[i] = NULL; + } + } +} + + +status_t +VideoConsumer::Connected(const media_source& producer, + const media_destination& where, const media_format& format, + media_input* outInput) +{ + fIn.source = producer; + fIn.format = format; + fIn.node = Node(); + sprintf(fIn.name, "Video Consumer"); + *outInput = fIn; + + uint32 userData = 0; + int32 changeTag = 1; + status_t ret = CreateBuffers(format); + if (ret == B_OK) { + ret = SetOutputBuffersFor(producer, fIn.destination, + fBuffers, &userData, &changeTag, true); + if (ret != B_OK) + fprintf(stderr, "SetOutputBuffersFor() failed: %s\n", strerror(ret)); + + fIn.format.u.raw_video.display.bytes_per_row + = fBitmap[0]->BytesPerRow(); + } else { + fprintf(stderr, "VideoConsumer::Connected - COULDN'T CREATE BUFFERS\n"); + return ret; + } + + *outInput = fIn; + fConnectionActive = true; + + return B_OK; +} + + +void +VideoConsumer::Disconnected(const media_source& producer, + const media_destination& where) +{ + if (where != fIn.destination || producer != fIn.source) + return; + + int32 changeTag = 0; + SetOutputBuffersFor(producer, fIn.destination, NULL, NULL, &changeTag, + false); + if (fOurBuffers) { + status_t reclaimError = fBuffers->ReclaimAllBuffers(); + if (reclaimError != B_OK) { + fprintf(stderr, "VideoConsumer::Disconnected() - Failed to " + "reclaim our buffers: %s\n", strerror(reclaimError)); + } + } + // disconnect the connection + fIn.source = media_source::null; + fConnectionActive = false; + + _UnsetTargetBuffer(); +} + + +status_t +VideoConsumer::AcceptFormat(const media_destination& dest, media_format* format) +{ + if (dest != fIn.destination) { + fprintf(stderr, "VideoConsumer::AcceptFormat - BAD DESTINATION\n"); + return B_MEDIA_BAD_DESTINATION; + } + + if (format->type == B_MEDIA_NO_TYPE) + format->type = B_MEDIA_RAW_VIDEO; + + if (format->type != B_MEDIA_RAW_VIDEO) { + fprintf(stderr, "VideoConsumer::AcceptFormat - BAD FORMAT\n"); + return B_MEDIA_BAD_FORMAT; + } + + if (format->u.raw_video.display.format + != media_raw_video_format::wildcard.display.format) { + uint32 flags = 0; + bool supported = bitmaps_support_space( + format->u.raw_video.display.format, &flags); + + if (!supported) { + fprintf(stderr, "AcceptFormat - unsupported color space for BBitmaps !\n"); + return B_MEDIA_BAD_FORMAT; + } + if (flags & B_VIEWS_SUPPORT_DRAW_BITMAP == 0) { + fprintf(stderr, "AcceptFormat - BViews cannot draw bitmaps in given colorspace !\n"); + return B_MEDIA_BAD_FORMAT; + } + } + + return B_OK; +} + + +status_t +VideoConsumer::GetNextInput(int32* cookie, media_input* outInput) +{ + if (*cookie < 1) { + fIn.node = Node(); + fIn.destination.id = *cookie; + sprintf(fIn.name, "Video Consumer"); + *outInput = fIn; + (*cookie)++; + return B_OK; + } + return B_MEDIA_BAD_DESTINATION; +} + + +void +VideoConsumer::DisposeInputCookie(int32 /*cookie*/) +{ +} + + +status_t +VideoConsumer::GetLatencyFor(const media_destination& whom, + bigtime_t* _latency, media_node_id* _timeSource) +{ + if (whom != fIn.destination) + return B_MEDIA_BAD_DESTINATION; + + *_latency = fMyLatency; + *_timeSource = TimeSource()->ID(); + return B_OK; +} + + +status_t +VideoConsumer::FormatChanged(const media_source& producer, + const media_destination& consumer, int32 fromChangeCount, + const media_format& format) +{ + if (consumer != fIn.destination) + return B_MEDIA_BAD_DESTINATION; + + if (producer != fIn.source) + return B_MEDIA_BAD_SOURCE; + + fIn.format = format; + + return CreateBuffers(format); +} + + +void +VideoConsumer::HandleEvent(const media_timed_event* event, bigtime_t lateness, + bool realTimeEvent) +{ + switch (event->type) { + case BTimedEventQueue::B_START: + _SetPerformanceTimeBase(event->event_time); + break; + case BTimedEventQueue::B_WARP: + case BTimedEventQueue::B_SEEK: + _SetPerformanceTimeBase(event->bigdata); + break; + case BTimedEventQueue::B_STOP: + EventQueue()->FlushEvents(event->event_time, BTimedEventQueue::B_ALWAYS, + true, BTimedEventQueue::B_HANDLE_BUFFER); + _UnsetTargetBuffer(); + break; + case BTimedEventQueue::B_HANDLE_BUFFER: + _HandleBuffer(static_cast(event->pointer)); + break; + default: + fprintf(stderr, "VideoConsumer::HandleEvent - BAD EVENT\n"); + break; + } +} + + +void +VideoConsumer::_SetPerformanceTimeBase(bigtime_t performanceTime) +{ + fPerformanceTimeBase = performanceTime; +} + + +void +VideoConsumer::_HandleBuffer(BBuffer* buffer) +{ + if (RunState() != B_STARTED || !fConnectionActive) { + buffer->Recycle(); + return; + } + + uint32 index = 0; + fOurBuffers = true; + while (index < kBufferCount) { + if (buffer->ID() == fBufferMap[index]->ID()) + break; + else + index++; + } + if (index == kBufferCount) { + fOurBuffers = false; + index = (fLastBufferIndex + 1) % kBufferCount; + } + + bool recycle = true; + bigtime_t now = TimeSource()->Now(); + + if (!fOurBuffers) { + memcpy(fBitmap[index]->Bits(), buffer->Data(), + fBitmap[index]->BitsLength()); + } + + bigtime_t tooEarly = buffer->Header()->start_time - now; + if (tooEarly > 3000) + snooze(tooEarly); + + fTargetLock.Lock(); + + VideoCaptureCapability frameInfo; + frameInfo.width = fBitmap[index]->Bounds().Width() + 1; + frameInfo.height = fBitmap[index]->Bounds().Height() + 1; + frameInfo.videoType = VideoType::kARGB; + + fVideoCapture->IncomingFrame((unsigned char*)fBitmap[index]->Bits(), + fBitmap[index]->BitsLength(), frameInfo); + + if (fOurBuffers) { + if (fLastBufferIndex >= 0) + fBufferMap[fLastBufferIndex]->Recycle(); + recycle = false; + } + fLastBufferIndex = index; + + fTargetLock.Unlock(); + + if (recycle) + buffer->Recycle(); +} + + +void +VideoConsumer::_UnsetTargetBuffer() +{ + fTargetLock.Lock(); + if (fLastBufferIndex >= 0) { + if (fOurBuffers) + fBufferMap[fLastBufferIndex]->Recycle(); + fLastBufferIndex = -1; + } + fTargetLock.Unlock(); +} + +} +} diff --git a/src/modules/video_capture/haiku/video_consumer.h b/src/modules/video_capture/haiku/video_consumer.h new file mode 100644 index 0000000..7308f0c --- /dev/null +++ b/src/modules/video_capture/haiku/video_consumer.h @@ -0,0 +1,123 @@ +/* + * Copyright 2021 Gerasim Troeglazov + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef VIDEO_CONSUMER_H +#define VIDEO_CONSUMER_H + +#include "modules/video_capture/video_capture_defines.h" +#include "modules/video_capture/video_capture_impl.h" + +#include +#include +#include + +class BBitmap; + +namespace webrtc { +namespace videocapturemodule { + +static const unsigned int kBufferCount = 4; + + +class VideoConsumer : public BMediaEventLooper, public BBufferConsumer { +public: + VideoConsumer( + const char* name, + BMediaAddOn* addon, + const uint32 internal_id); + ~VideoConsumer(); +public: + void SetVideoCapture(VideoCaptureImpl *impl); + // BMediaNode interface +public: + virtual BMediaAddOn* AddOn(int32* cookie) const; + +protected: + virtual void NodeRegistered(); + virtual status_t RequestCompleted( + const media_request_info& info); + + virtual status_t HandleMessage(int32 message, const void* data, + size_t size); + + // BMediaEventLooper interface +protected: + virtual void HandleEvent(const media_timed_event* event, + bigtime_t lateness, bool realTimeEvent); + + // BBufferConsumer interface +public: + virtual status_t AcceptFormat(const media_destination& dest, + media_format* format); + virtual status_t GetNextInput(int32* cookie, + media_input* _input); + + virtual void DisposeInputCookie(int32 cookie); + +protected: + virtual void BufferReceived(BBuffer* buffer); + +private: + virtual void ProducerDataStatus( + const media_destination& forWhom, + int32 status, + bigtime_t atMediaTime); + virtual status_t GetLatencyFor( + const media_destination& forWhom, + bigtime_t* outLatency, + media_node_id* outId); + virtual status_t Connected(const media_source& producer, + const media_destination& where, + const media_format& withFormat, + media_input* outInput); + virtual void Disconnected(const media_source& producer, + const media_destination& where); + virtual status_t FormatChanged(const media_source& producer, + const media_destination& consumer, + int32 from_change_count, + const media_format& format); + + // VideoConsumer +public: + status_t CreateBuffers( + const media_format& withFormat); + + void DeleteBuffers(); + +private: + void _SetPerformanceTimeBase( + bigtime_t performanceTime); + void _HandleBuffer(BBuffer* buffer); + void _UnsetTargetBuffer(); + +private: + int32 fInternalID; + BMediaAddOn* fAddOn; + + bool fConnectionActive; + media_input fIn; + bigtime_t fMyLatency; + bigtime_t fPerformanceTimeBase; + + BBitmap* fBitmap[kBufferCount]; + bool fOurBuffers; + BBufferGroup* fBuffers; + BBuffer* fBufferMap[kBufferCount]; + + BLocker fTargetLock; + int32 fLastBufferIndex; + + VideoCaptureImpl *fVideoCapture; +}; + +} // namespace videocapturemodule +} // namespace webrtc + +#endif // VIDEO_CONSUMER_H diff --git a/src/rtc_base/BUILD.gn b/src/rtc_base/BUILD.gn index 2cf9c11..cd10a6d 100644 --- a/src/rtc_base/BUILD.gn +++ b/src/rtc_base/BUILD.gn @@ -679,7 +679,7 @@ rtc_source_set("rtc_operations_chain") { absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] } -if (rtc_enable_libevent) { +if (rtc_enable_libevent && !is_haiku) { rtc_library("rtc_task_queue_libevent") { visibility = [ "../api/task_queue:default_task_queue_factory" ] sources = [ diff --git a/src/rtc_base/byte_order.h b/src/rtc_base/byte_order.h index 0ebaaaf..1e9566b 100644 --- a/src/rtc_base/byte_order.h +++ b/src/rtc_base/byte_order.h @@ -90,7 +90,7 @@ #error WEBRTC_ARCH_BIG_ENDIAN or WEBRTC_ARCH_LITTLE_ENDIAN must be defined. #endif // defined(WEBRTC_ARCH_LITTLE_ENDIAN) -#elif defined(WEBRTC_LINUX) +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_HAIKU) #include #elif defined(WEBRTC_FREEBSD) || defined(WEBRTC_OPENBSD) #include diff --git a/src/rtc_base/ip_address.cc b/src/rtc_base/ip_address.cc index 04fbc9b..93c7fe3 100644 --- a/src/rtc_base/ip_address.cc +++ b/src/rtc_base/ip_address.cc @@ -13,6 +13,9 @@ #include #include "absl/strings/string_view.h" +#if defined(WEBRTC_HAIKU) +#include +#endif #ifdef OPENBSD #include #endif @@ -31,6 +34,15 @@ namespace rtc { // Prefixes used for categorizing IPv6 addresses. +#if defined(WEBRTC_HAIKU) +static const in6_addr kV4MappedPrefix = { + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0}}; +static const in6_addr k6To4Prefix = {{0x20, 0x02, 0}}; +static const in6_addr kTeredoPrefix = {{0x20, 0x01, 0x00, 0x00}}; +static const in6_addr kV4CompatibilityPrefix = {{0}}; +static const in6_addr k6BonePrefix = {{0x3f, 0xfe, 0}}; +static const in6_addr kPrivateNetworkPrefix = {{0xFD}}; +#else static const in6_addr kV4MappedPrefix = { {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0}}}; static const in6_addr k6To4Prefix = {{{0x20, 0x02, 0}}}; @@ -38,6 +50,7 @@ static const in6_addr kTeredoPrefix = {{{0x20, 0x01, 0x00, 0x00}}}; static const in6_addr kV4CompatibilityPrefix = {{{0}}}; static const in6_addr k6BonePrefix = {{{0x3f, 0xfe, 0}}}; static const in6_addr kPrivateNetworkPrefix = {{{0xFD}}}; +#endif static bool IPIsHelper(const IPAddress& ip, const in6_addr& tomatch, diff --git a/src/rtc_base/logging.cc b/src/rtc_base/logging.cc index 61a3c66..c61a47e 100644 --- a/src/rtc_base/logging.cc +++ b/src/rtc_base/logging.cc @@ -97,7 +97,7 @@ std::string LogLineRef::DefaultLogLine() const { log_output << timestamp; } if (thread_id_.has_value()) { - log_output << "[" << *thread_id_ << "] "; + log_output << "[" << (uint64_t)(*thread_id_) << "] "; } if (!filename_.empty()) { #if defined(WEBRTC_ANDROID) diff --git a/src/rtc_base/network.cc b/src/rtc_base/network.cc index 4be6eed..691fb2e 100644 --- a/src/rtc_base/network.cc +++ b/src/rtc_base/network.cc @@ -630,8 +630,8 @@ void BasicNetworkManager::ConvertIfAddrs( continue; } // Skip ones which are down. - if (!(cursor->ifa_flags & IFF_RUNNING)) { - RTC_LOG(LS_INFO) << "Skip interface because of not IFF_RUNNING: " + if (!(cursor->ifa_flags & IFF_LINK)) { + RTC_LOG(LS_INFO) << "Skip interface because of not IFF_LINK: " << ip.ToSensitiveString(); continue; } diff --git a/src/rtc_base/physical_socket_server.cc b/src/rtc_base/physical_socket_server.cc index 727e200..5ce1edf 100644 --- a/src/rtc_base/physical_socket_server.cc +++ b/src/rtc_base/physical_socket_server.cc @@ -334,7 +334,7 @@ int PhysicalSocket::SetOption(Option opt, int value) { value <<= 2; #endif } -#if defined(WEBRTC_POSIX) +#if defined(WEBRTC_POSIX) && !defined(WEBRTC_HAIKU) if (sopt == IPV6_TCLASS) { // Set the IPv4 option in all cases to support dual-stack sockets. // Don't bother checking the return code, as this is expected to fail if @@ -687,7 +687,7 @@ int PhysicalSocket::TranslateOption(Option opt, int* slevel, int* sopt) { *sopt = TCP_NODELAY; break; case OPT_DSCP: -#if defined(WEBRTC_POSIX) +#if defined(WEBRTC_POSIX) && !defined(WEBRTC_HAIKU) if (family_ == AF_INET6) { *slevel = IPPROTO_IPV6; *sopt = IPV6_TCLASS; diff --git a/src/rtc_base/platform_thread_types.h b/src/rtc_base/platform_thread_types.h index 6046281..0a113ad 100644 --- a/src/rtc_base/platform_thread_types.h +++ b/src/rtc_base/platform_thread_types.h @@ -38,6 +38,9 @@ typedef DWORD PlatformThreadRef; #elif defined(WEBRTC_FUCHSIA) typedef zx_handle_t PlatformThreadId; typedef zx_handle_t PlatformThreadRef; +#elif defined(WEBRTC_HAIKU) +typedef pthread_t PlatformThreadId; +typedef pthread_t PlatformThreadRef; #elif defined(WEBRTC_POSIX) #if defined(WEBRTC_MAC) || defined(WEBRTC_IOS) typedef mach_port_t PlatformThreadId; diff --git a/src/rtc_base/system/rtc_export.h b/src/rtc_base/system/rtc_export.h index d1eb60a..9dc761d 100644 --- a/src/rtc_base/system/rtc_export.h +++ b/src/rtc_base/system/rtc_export.h @@ -28,7 +28,7 @@ #else // WEBRTC_WIN -#if __has_attribute(visibility) && defined(WEBRTC_LIBRARY_IMPL) +#if defined(WEBRTC_LIBRARY_IMPL) #define RTC_EXPORT __attribute__((visibility("default"))) #endif diff --git a/src/rtc_base/system/rtc_export_template.h b/src/rtc_base/system/rtc_export_template.h index 4ac7043..5fe950f 100644 --- a/src/rtc_base/system/rtc_export_template.h +++ b/src/rtc_base/system/rtc_export_template.h @@ -185,7 +185,7 @@ RTC_EXPORT_TEMPLATE_TEST(DEFAULT, ); // NOLINT RTC_EXPORT_TEMPLATE_TEST(DEFAULT, __attribute__((visibility("default")))); -RTC_EXPORT_TEMPLATE_TEST(MSVC_HACK, __declspec(dllexport)); +//RTC_EXPORT_TEMPLATE_TEST(MSVC_HACK, __declspec(dllexport)); RTC_EXPORT_TEMPLATE_TEST(DEFAULT, __declspec(dllimport)); #undef RTC_EXPORT_TEMPLATE_TEST -- 2.45.2 From f4560193b4024a83faa3e9ef85f6fa2ea09704ff Mon Sep 17 00:00:00 2001 From: Gerasim Troeglazov <3dEyes@gmail.com> Date: Fri, 2 Aug 2024 09:49:48 +1000 Subject: Disable WebRTC-SCM-Timestamp experiment for Haiku diff --git a/src/rtc_base/async_udp_socket.cc b/src/rtc_base/async_udp_socket.cc index 3d258bc..f2d42bf 100644 --- a/src/rtc_base/async_udp_socket.cc +++ b/src/rtc_base/async_udp_socket.cc @@ -24,7 +24,11 @@ namespace rtc { // Returns true if the experiement "WebRTC-SCM-Timestamp" is explicitly // disabled. static bool IsScmTimeStampExperimentDisabled() { +#if defined(WEBRTC_HAIKU) + return true; +#else return webrtc::field_trial::IsDisabled("WebRTC-SCM-Timestamp"); +#endif } AsyncUDPSocket* AsyncUDPSocket::Create(Socket* socket, diff --git a/src/rtc_base/physical_socket_server.cc b/src/rtc_base/physical_socket_server.cc index 5ce1edf..de8c2b7 100644 --- a/src/rtc_base/physical_socket_server.cc +++ b/src/rtc_base/physical_socket_server.cc @@ -57,6 +57,11 @@ #include #endif +#if defined(WEBRTC_HAIKU) +#define SO_TIMESTAMP 0 +#define SCM_TIMESTAMP 0 +#endif + #if defined(WEBRTC_WIN) #define LAST_SYSTEM_ERROR (::GetLastError()) #elif defined(__native_client__) && __native_client__ @@ -123,7 +128,11 @@ class ScopedSetTrue { // Returns true if the experiement "WebRTC-SCM-Timestamp" is explicitly // disabled. bool IsScmTimeStampExperimentDisabled() { +#if defined(WEBRTC_HAIKU) + return true; +#else return webrtc::field_trial::IsDisabled("WebRTC-SCM-Timestamp"); +#endif } } // namespace -- 2.45.2