1 #include "tgcalls/platform/tdesktop/VideoCapturerInterfaceImpl.h"
2
3 #include "tgcalls/platform/tdesktop/VideoCapturerTrackSource.h"
4 #include "tgcalls/platform/tdesktop/VideoCameraCapturer.h"
5
6 #ifndef TGCALLS_UWP_DESKTOP_CAPTURE
7 #include "tgcalls/desktop_capturer/DesktopCaptureSourceHelper.h"
8 #endif // TGCALLS_DISABLE_DESKTOP_CAPTURE
9
10 #include "api/video_track_source_proxy.h"
11
12 namespace tgcalls {
13 namespace {
14
GetSink(const rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> & nativeSource)15 std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> GetSink(
16 const rtc::scoped_refptr<
17 webrtc::VideoTrackSourceInterface> &nativeSource) {
18 const auto proxy = static_cast<webrtc::VideoTrackSourceProxy*>(
19 nativeSource.get());
20 const auto internal = static_cast<VideoCapturerTrackSource*>(
21 proxy->internal());
22 return internal->sink();
23 }
24
25 } // namespace
26
VideoCapturerInterfaceImpl(rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> source,std::string deviceId,std::function<void (VideoState)> stateUpdated,std::shared_ptr<PlatformContext> platformContext,std::pair<int,int> & outResolution)27 VideoCapturerInterfaceImpl::VideoCapturerInterfaceImpl(
28 rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> source,
29 std::string deviceId,
30 std::function<void(VideoState)> stateUpdated,
31 std::shared_ptr<PlatformContext> platformContext,
32 std::pair<int, int> &outResolution)
33 : _source(source)
34 , _sink(GetSink(source))
35 , _stateUpdated(stateUpdated) {
36 #ifdef TGCALLS_UWP_DESKTOP_CAPTURE
37 if (deviceId == "GraphicsCaptureItem")
38 {
39 auto uwpContext = std::static_pointer_cast<UwpContext>(platformContext);
40
41 _screenCapturer = std::make_unique<UwpScreenCapturer>(_sink, uwpContext->item);
42 _screenCapturer->setState(VideoState::Active);
43 outResolution = _screenCapturer->resolution();
44 }
45 else
46 #else
47 if (const auto source = DesktopCaptureSourceForKey(deviceId)) {
48 const auto data = DesktopCaptureSourceData{
49 /*.aspectSize = */{ 1280, 720 },
50 /*.fps = */24.,
51 /*.captureMouse = */(deviceId != "desktop_capturer_pipewire"),
52 };
53 _desktopCapturer = std::make_unique<DesktopCaptureSourceHelper>(
54 source,
55 data);
56 _desktopCapturer->setOutput(_sink);
57 _desktopCapturer->start();
58 outResolution = { 1280, 960 };
59 } else if (!ShouldBeDesktopCapture(deviceId))
60 #endif // TGCALLS_UWP_DESKTOP_CAPTURE
61 {
62 _cameraCapturer = std::make_unique<VideoCameraCapturer>(_sink);
63 _cameraCapturer->setDeviceId(deviceId);
64 _cameraCapturer->setState(VideoState::Active);
65 outResolution = _cameraCapturer->resolution();
66 }
67 }
68
~VideoCapturerInterfaceImpl()69 VideoCapturerInterfaceImpl::~VideoCapturerInterfaceImpl() {
70 }
71
setState(VideoState state)72 void VideoCapturerInterfaceImpl::setState(VideoState state) {
73 #ifdef TGCALLS_UWP_DESKTOP_CAPTURE
74 if (_screenCapturer) {
75 _screenCapturer->setState(state);
76 } else
77 #else
78 if (_desktopCapturer) {
79 if (state == VideoState::Active) {
80 _desktopCapturer->start();
81 } else {
82 _desktopCapturer->stop();
83 }
84 } else
85 #endif // TGCALLS_UWP_DESKTOP_CAPTURE
86 if (_cameraCapturer) {
87 _cameraCapturer->setState(state);
88 }
89 if (_stateUpdated) {
90 _stateUpdated(state);
91 }
92 }
93
setPreferredCaptureAspectRatio(float aspectRatio)94 void VideoCapturerInterfaceImpl::setPreferredCaptureAspectRatio(
95 float aspectRatio) {
96 if (_cameraCapturer) {
97 _cameraCapturer->setPreferredCaptureAspectRatio(aspectRatio);
98 }
99 }
100
setUncroppedOutput(std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> sink)101 void VideoCapturerInterfaceImpl::setUncroppedOutput(
102 std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> sink) {
103 if (_uncroppedSink != nullptr) {
104 _source->RemoveSink(_uncroppedSink.get());
105 }
106 _uncroppedSink = sink;
107 if (_uncroppedSink != nullptr) {
108 _source->AddOrUpdateSink(
109 _uncroppedSink.get(),
110 rtc::VideoSinkWants());
111 }
112 }
113
setOnFatalError(std::function<void ()> error)114 void VideoCapturerInterfaceImpl::setOnFatalError(std::function<void()> error) {
115 #ifdef TGCALLS_UWP_DESKTOP_CAPTURE
116 if (_screenCapturer) {
117 _screenCapturer->setOnFatalError(std::move(error));
118 } else if (!_screenCapturer && !_cameraCapturer && error) {
119 error();
120 }
121 #else // TGCALLS_UWP_DESKTOP_CAPTURE
122 if (_desktopCapturer) {
123 _desktopCapturer->setOnFatalError(std::move(error));
124 } else if (!_desktopCapturer && !_cameraCapturer && error) {
125 error();
126 }
127 #endif // TGCALLS_UWP_DESKTOP_CAPTURE
128 if (_cameraCapturer) {
129 _cameraCapturer->setOnFatalError(std::move(error));
130 }
131 }
132
setOnPause(std::function<void (bool)> pause)133 void VideoCapturerInterfaceImpl::setOnPause(std::function<void(bool)> pause) {
134 #ifdef TGCALLS_UWP_DESKTOP_CAPTURE
135 if (_screenCapturer) {
136 _screenCapturer->setOnPause(std::move(pause));
137 }
138 #else // TGCALLS_UWP_DESKTOP_CAPTURE
139 if (_desktopCapturer) {
140 _desktopCapturer->setOnPause(std::move(pause));
141 }
142 #endif // TGCALLS_UWP_DESKTOP_CAPTURE
143 }
144
145 } // namespace tgcalls
146