diff --git a/media-libs/tg_owt/patches/tg_owt-0.0.20210627.patchset b/media-libs/tg_owt/patches/tg_owt-0.0.20210627.patchset index 4a6320648..1f7195f6a 100644 --- a/media-libs/tg_owt/patches/tg_owt-0.0.20210627.patchset +++ b/media-libs/tg_owt/patches/tg_owt-0.0.20210627.patchset @@ -1,11 +1,11 @@ -From 0920a87753099a5a2f6823eaf168bf82b8586877 Mon Sep 17 00:00:00 2001 +From d0793b34c7d6c4e3fe2f3e6fb325143186bea54e Mon Sep 17 00:00:00 2001 From: Gerasim Troeglazov <3dEyes@gmail.com> -Date: Thu, 22 Jul 2021 19:58:59 +1000 +Date: Wed, 11 Aug 2021 21:09:47 +1000 Subject: Add Haiku support diff --git a/CMakeLists.txt b/CMakeLists.txt -index f5696ed..5106673 100644 +index f5696ed..819d371 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,7 +71,7 @@ include(cmake/libsrtp.cmake) @@ -51,16 +51,17 @@ index f5696ed..5106673 100644 api/task_queue/default_task_queue_factory_libevent.cc api/task_queue/default_task_queue_factory_win.cc api/task_queue/task_queue_base.cc -@@ -1458,6 +1461,8 @@ PRIVATE +@@ -1458,6 +1461,9 @@ PRIVATE modules/video_capture/device_info_impl.cc modules/video_capture/linux/device_info_linux.cc modules/video_capture/linux/video_capture_linux.cc + 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 -@@ -2006,6 +2011,7 @@ PRIVATE +@@ -2006,6 +2012,7 @@ PRIVATE modules/desktop_capture/mouse_cursor.h modules/desktop_capture/mouse_cursor_monitor.h modules/desktop_capture/mouse_cursor_monitor_linux.cc @@ -68,7 +69,7 @@ index f5696ed..5106673 100644 modules/desktop_capture/mouse_cursor_monitor_mac.mm modules/desktop_capture/mouse_cursor_monitor_win.cc modules/desktop_capture/resolution_tracker.cc -@@ -2017,8 +2023,10 @@ PRIVATE +@@ -2017,8 +2024,10 @@ PRIVATE modules/desktop_capture/screen_capturer_helper.h modules/desktop_capture/screen_capturer_darwin.mm modules/desktop_capture/screen_capturer_linux.cc @@ -79,7 +80,18 @@ index f5696ed..5106673 100644 modules/desktop_capture/window_capturer_mac.mm modules/desktop_capture/window_capturer_win.cc modules/desktop_capture/window_finder.cc -@@ -2307,7 +2315,7 @@ else() +@@ -2033,6 +2042,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/base_capturer_pipewire.cc + modules/desktop_capture/linux/base_capturer_pipewire.h +@@ -2307,7 +2320,7 @@ else() ) endif() @@ -88,7 +100,7 @@ index f5696ed..5106673 100644 remove_target_sources(tg_owt ${webrtc_loc} rtc_base/task_queue_libevent.cc rtc_base/task_queue_libevent.h -@@ -2323,7 +2331,7 @@ else() +@@ -2323,7 +2336,7 @@ else() endif() set(platform_export) @@ -185,6 +197,167 @@ index 1072057..745f5b7 100644 sources += [ "default_task_queue_factory_libevent.cc" ] deps += [ "../../rtc_base:rtc_task_queue_libevent" ] } else if (is_mac || is_ios) { +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..b541795 +--- /dev/null ++++ b/src/modules/desktop_capture/haiku/screen_capturer_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_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 "rtc_base/constructor_magic.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; ++ ++ RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerHaiku); ++}; ++ ++} ++ ++#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 @@ -232,12 +405,12 @@ index 0000000..8ea2aa2 +} // 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..da0428e +index 0000000..63ceecc --- /dev/null +++ b/src/modules/desktop_capture/screen_capturer_haiku.cc -@@ -0,0 +1,24 @@ +@@ -0,0 +1,26 @@ +/* -+ * Copyright 2018 The WebRTC project authors. All Rights Reserved. ++ * 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 @@ -251,23 +424,25 @@ index 0000000..da0428e +#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 nullptr; ++ 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..1092898 +index 0000000..dab0db5 --- /dev/null +++ b/src/modules/desktop_capture/window_capturer_haiku.cc -@@ -0,0 +1,24 @@ +@@ -0,0 +1,66 @@ +/* -+ * Copyright 2018 The WebRTC project authors. All Rights Reserved. ++ * 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 @@ -276,26 +451,78 @@ index 0000000..1092898 + * 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/desktop_frame.h" ++#include "rtc_base/constructor_magic.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; ++ RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerHaiku); ++}; ++ ++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 nullptr; ++ 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..6f1c551 +index 0000000..aeddaef --- /dev/null +++ b/src/modules/video_capture/haiku/device_info_haiku.cc -@@ -0,0 +1,69 @@ +@@ -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 @@ -328,7 +555,34 @@ index 0000000..6f1c551 +DeviceInfoHaiku::~DeviceInfoHaiku() {} + +uint32_t DeviceInfoHaiku::NumberOfDevices() { -+ return 0; ++ 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, @@ -336,45 +590,100 @@ index 0000000..6f1c551 + uint32_t deviceNameLength, + char* deviceUniqueIdUTF8, + uint32_t deviceUniqueIdUTF8Length, -+ char* /*productUniqueIdUTF8*/, -+ uint32_t /*productUniqueIdUTF8Length*/) { -+ return -1; ++ 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) { -+ return -1; ++ _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; -+} -+ -+bool DeviceInfoHaiku::IsDeviceNameMatches(const char* name, -+ const char* deviceUniqueIdUTF8) { -+ return false; -+} -+ -+int32_t DeviceInfoHaiku::FillCapabilities(int fd) { -+ return -1; ++ 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..96352fa +index 0000000..b5ffe94 --- /dev/null +++ b/src/modules/video_capture/haiku/device_info_haiku.h -@@ -0,0 +1,36 @@ +@@ -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" + @@ -398,21 +707,27 @@ index 0000000..96352fa + void*, + uint32_t, + uint32_t) override; -+ int32_t FillCapabilities(int fd); + int32_t Init() override; -+ -+ private: -+ bool IsDeviceNameMatches(const char* name, const char* deviceUniqueIdUTF8); +}; +} // 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..94a79df +index 0000000..86d8d20 --- /dev/null +++ b/src/modules/video_capture/haiku/video_capture_haiku.cc -@@ -0,0 +1,29 @@ +@@ -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 @@ -438,16 +753,188 @@ index 0000000..94a79df +namespace videocapturemodule { +rtc::scoped_refptr VideoCaptureImpl::Create( + const char* deviceUniqueId) { -+ return nullptr; ++ 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..ac60bb0 +index 0000000..5bce5bd --- /dev/null +++ b/src/modules/video_capture/haiku/video_capture_haiku.h -@@ -0,0 +1,20 @@ +@@ -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_ + @@ -456,18 +943,656 @@ index 0000000..ac60bb0 + +#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 3cf1a9f..013e361 100644 --- a/src/rtc_base/BUILD.gn diff --git a/media-libs/tg_owt/tg_owt-0.0.20210627.recipe b/media-libs/tg_owt/tg_owt-0.0.20210627.recipe index eaa33c65d..fa03fb115 100644 --- a/media-libs/tg_owt/tg_owt-0.0.20210627.recipe +++ b/media-libs/tg_owt/tg_owt-0.0.20210627.recipe @@ -3,7 +3,7 @@ DESCRIPTION="Telegram Desktop's fork of Google's WebRTC." HOMEPAGE="https://github.com/desktop-app/tg_owt" COPYRIGHT="2013-2021 Telegram" LICENSE="BSD (3-clause)" -REVISION="1" +REVISION="2" srcGitRev="91d836dc84a16584c6ac52b36c04c0de504d9c34" SOURCE_URI="https://github.com/desktop-app/tg_owt/archive/$srcGitRev.tar.gz" SOURCE_DIR="tg_owt-$srcGitRev"