|
33 | 33 | namespace jni |
34 | 34 | { |
35 | 35 | VideoTrackDesktopSource::VideoTrackDesktopSource() : |
36 | | - AdaptedVideoTrackSource(), |
| 36 | + VideoTrackSource(/*remote=*/false), |
37 | 37 | frameRate(20), |
38 | 38 | isCapturing(false), |
39 | 39 | focusSelectedSource(true), |
@@ -88,29 +88,104 @@ namespace jni |
88 | 88 | } |
89 | 89 | } |
90 | 90 |
|
| 91 | + void VideoTrackDesktopSource::AddOrUpdateSink(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink, const rtc::VideoSinkWants& wants) |
| 92 | + { |
| 93 | + if (wants.is_active) { |
| 94 | + broadcaster.AddOrUpdateSink(sink, wants); |
| 95 | + |
| 96 | + updateVideoAdapter(); |
| 97 | + } |
| 98 | + } |
| 99 | + |
| 100 | + void VideoTrackDesktopSource::RemoveSink(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) |
| 101 | + { |
| 102 | + broadcaster.RemoveSink(sink); |
| 103 | + |
| 104 | + updateVideoAdapter(); |
| 105 | + } |
| 106 | + |
| 107 | + void VideoTrackDesktopSource::updateVideoAdapter() |
| 108 | + { |
| 109 | + videoAdapter.OnSinkWants(broadcaster.wants()); |
| 110 | + } |
| 111 | + |
| 112 | + void VideoTrackDesktopSource::OnFrameDropped() |
| 113 | + { |
| 114 | + broadcaster.OnDiscardedFrame(); |
| 115 | + } |
| 116 | + |
| 117 | + rtc::VideoSourceInterface<webrtc::VideoFrame>* VideoTrackDesktopSource::source() |
| 118 | + { |
| 119 | + return this; |
| 120 | + } |
| 121 | + |
91 | 122 | void VideoTrackDesktopSource::terminate() |
92 | 123 | { |
93 | 124 | // Notify the track that we are permanently done. |
94 | 125 | sourceState = kEnded; |
95 | 126 | FireOnChanged(); |
96 | 127 | } |
97 | 128 |
|
98 | | - bool VideoTrackDesktopSource::is_screencast() const { |
| 129 | + bool VideoTrackDesktopSource::GetStats(webrtc::VideoTrackSourceInterface::Stats * stats) |
| 130 | + { |
| 131 | + webrtc::MutexLock lock(&statsMutex); |
| 132 | + |
| 133 | + if (!stats) { |
| 134 | + return false; |
| 135 | + } |
| 136 | + |
| 137 | + *stats = *stats; |
| 138 | + |
| 139 | + return true; |
| 140 | + } |
| 141 | + |
| 142 | + void VideoTrackDesktopSource::ProcessConstraints(const webrtc::VideoTrackSourceConstraints & constraints) |
| 143 | + { |
| 144 | + broadcaster.ProcessConstraints(constraints); |
| 145 | + } |
| 146 | + |
| 147 | + bool VideoTrackDesktopSource::is_screencast() const |
| 148 | + { |
99 | 149 | return true; |
100 | 150 | } |
101 | 151 |
|
102 | | - std::optional<bool> VideoTrackDesktopSource::needs_denoising() const { |
| 152 | + std::optional<bool> VideoTrackDesktopSource::needs_denoising() const |
| 153 | + { |
103 | 154 | return false; |
104 | 155 | } |
105 | 156 |
|
106 | | - webrtc::MediaSourceInterface::SourceState VideoTrackDesktopSource::state() const { |
| 157 | + webrtc::MediaSourceInterface::SourceState VideoTrackDesktopSource::state() const |
| 158 | + { |
107 | 159 | return sourceState; |
108 | 160 | } |
109 | 161 |
|
110 | | - bool VideoTrackDesktopSource::remote() const { |
| 162 | + bool VideoTrackDesktopSource::remote() const |
| 163 | + { |
111 | 164 | return false; |
112 | 165 | } |
113 | 166 |
|
| 167 | + bool VideoTrackDesktopSource::AdaptFrame(int width, int height, int64_t time_us, int* out_width, int* out_height, int* crop_width, int* crop_height, int* crop_x, int* crop_y) |
| 168 | + { |
| 169 | + { |
| 170 | + webrtc::MutexLock lock(&statsMutex); |
| 171 | + stats = Stats{ width, height }; |
| 172 | + } |
| 173 | + |
| 174 | + if (!broadcaster.frame_wanted()) { |
| 175 | + return false; |
| 176 | + } |
| 177 | + |
| 178 | + if (!videoAdapter.AdaptFrameResolution(width, height, time_us * rtc::kNumNanosecsPerMicrosec, crop_width, crop_height, out_width, out_height)) { |
| 179 | + broadcaster.OnDiscardedFrame(); |
| 180 | + return false; |
| 181 | + } |
| 182 | + |
| 183 | + *crop_x = (width - *crop_width) / 2; |
| 184 | + *crop_y = (height - *crop_height) / 2; |
| 185 | + |
| 186 | + return true; |
| 187 | + } |
| 188 | + |
114 | 189 | void VideoTrackDesktopSource::OnCaptureResult(webrtc::DesktopCapturer::Result result, std::unique_ptr<webrtc::DesktopFrame> frame) |
115 | 190 | { |
116 | 191 | if (result != webrtc::DesktopCapturer::Result::SUCCESS) { |
@@ -149,8 +224,8 @@ namespace jni |
149 | 224 | int width = frame->size().width(); |
150 | 225 | int height = frame->size().height(); |
151 | 226 |
|
152 | | - int adapted_width; |
153 | | - int adapted_height; |
| 227 | + int adapted_width = width; |
| 228 | + int adapted_height = height; |
154 | 229 |
|
155 | 230 | int crop_x = 0; |
156 | 231 | int crop_y = 0; |
@@ -216,18 +291,19 @@ namespace jni |
216 | 291 |
|
217 | 292 | scaled_buffer->ScaleFrom(*buffer); |
218 | 293 |
|
219 | | - OnFrame(webrtc::VideoFrame::Builder() |
| 294 | + broadcaster.OnFrame(webrtc::VideoFrame::Builder() |
220 | 295 | .set_video_frame_buffer(scaled_buffer) |
221 | 296 | .set_rotation(webrtc::kVideoRotation_0) |
222 | 297 | .set_timestamp_us(time) |
223 | 298 | .build()); |
224 | 299 | } |
225 | 300 | else { |
226 | 301 | // No adaptations needed, just return the frame as is. |
227 | | - OnFrame(webrtc::VideoFrame::Builder() |
| 302 | + broadcaster.OnFrame(webrtc::VideoFrame::Builder() |
228 | 303 | .set_video_frame_buffer(buffer) |
229 | 304 | .set_rotation(webrtc::kVideoRotation_0) |
230 | 305 | .set_timestamp_us(time) |
| 306 | + .set_timestamp_rtp(0) |
231 | 307 | .build()); |
232 | 308 | } |
233 | 309 | } |
|
0 commit comments