1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright 2020 The WebRTC Project Authors. All rights reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker 11*d9f75844SAndroid Build Coastguard Worker #include "video/video_source_sink_controller.h" 12*d9f75844SAndroid Build Coastguard Worker 13*d9f75844SAndroid Build Coastguard Worker #include <algorithm> 14*d9f75844SAndroid Build Coastguard Worker #include <limits> 15*d9f75844SAndroid Build Coastguard Worker #include <utility> 16*d9f75844SAndroid Build Coastguard Worker 17*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/logging.h" 18*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/numerics/safe_conversions.h" 19*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/strings/string_builder.h" 20*d9f75844SAndroid Build Coastguard Worker 21*d9f75844SAndroid Build Coastguard Worker namespace webrtc { 22*d9f75844SAndroid Build Coastguard Worker VideoSourceSinkController(rtc::VideoSinkInterface<VideoFrame> * sink,rtc::VideoSourceInterface<VideoFrame> * source)23*d9f75844SAndroid Build Coastguard WorkerVideoSourceSinkController::VideoSourceSinkController( 24*d9f75844SAndroid Build Coastguard Worker rtc::VideoSinkInterface<VideoFrame>* sink, 25*d9f75844SAndroid Build Coastguard Worker rtc::VideoSourceInterface<VideoFrame>* source) 26*d9f75844SAndroid Build Coastguard Worker : sink_(sink), source_(source) { 27*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(sink_); 28*d9f75844SAndroid Build Coastguard Worker } 29*d9f75844SAndroid Build Coastguard Worker ~VideoSourceSinkController()30*d9f75844SAndroid Build Coastguard WorkerVideoSourceSinkController::~VideoSourceSinkController() { 31*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 32*d9f75844SAndroid Build Coastguard Worker } 33*d9f75844SAndroid Build Coastguard Worker SetSource(rtc::VideoSourceInterface<VideoFrame> * source)34*d9f75844SAndroid Build Coastguard Workervoid VideoSourceSinkController::SetSource( 35*d9f75844SAndroid Build Coastguard Worker rtc::VideoSourceInterface<VideoFrame>* source) { 36*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 37*d9f75844SAndroid Build Coastguard Worker 38*d9f75844SAndroid Build Coastguard Worker rtc::VideoSourceInterface<VideoFrame>* old_source = source_; 39*d9f75844SAndroid Build Coastguard Worker source_ = source; 40*d9f75844SAndroid Build Coastguard Worker 41*d9f75844SAndroid Build Coastguard Worker if (old_source != source && old_source) 42*d9f75844SAndroid Build Coastguard Worker old_source->RemoveSink(sink_); 43*d9f75844SAndroid Build Coastguard Worker 44*d9f75844SAndroid Build Coastguard Worker if (!source) 45*d9f75844SAndroid Build Coastguard Worker return; 46*d9f75844SAndroid Build Coastguard Worker 47*d9f75844SAndroid Build Coastguard Worker source->AddOrUpdateSink(sink_, CurrentSettingsToSinkWants()); 48*d9f75844SAndroid Build Coastguard Worker } 49*d9f75844SAndroid Build Coastguard Worker HasSource() const50*d9f75844SAndroid Build Coastguard Workerbool VideoSourceSinkController::HasSource() const { 51*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 52*d9f75844SAndroid Build Coastguard Worker return source_ != nullptr; 53*d9f75844SAndroid Build Coastguard Worker } 54*d9f75844SAndroid Build Coastguard Worker RequestRefreshFrame()55*d9f75844SAndroid Build Coastguard Workervoid VideoSourceSinkController::RequestRefreshFrame() { 56*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 57*d9f75844SAndroid Build Coastguard Worker if (source_) 58*d9f75844SAndroid Build Coastguard Worker source_->RequestRefreshFrame(); 59*d9f75844SAndroid Build Coastguard Worker } 60*d9f75844SAndroid Build Coastguard Worker PushSourceSinkSettings()61*d9f75844SAndroid Build Coastguard Workervoid VideoSourceSinkController::PushSourceSinkSettings() { 62*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 63*d9f75844SAndroid Build Coastguard Worker if (!source_) 64*d9f75844SAndroid Build Coastguard Worker return; 65*d9f75844SAndroid Build Coastguard Worker rtc::VideoSinkWants wants = CurrentSettingsToSinkWants(); 66*d9f75844SAndroid Build Coastguard Worker source_->AddOrUpdateSink(sink_, wants); 67*d9f75844SAndroid Build Coastguard Worker } 68*d9f75844SAndroid Build Coastguard Worker restrictions() const69*d9f75844SAndroid Build Coastguard WorkerVideoSourceRestrictions VideoSourceSinkController::restrictions() const { 70*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 71*d9f75844SAndroid Build Coastguard Worker return restrictions_; 72*d9f75844SAndroid Build Coastguard Worker } 73*d9f75844SAndroid Build Coastguard Worker pixels_per_frame_upper_limit() const74*d9f75844SAndroid Build Coastguard Workerabsl::optional<size_t> VideoSourceSinkController::pixels_per_frame_upper_limit() 75*d9f75844SAndroid Build Coastguard Worker const { 76*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 77*d9f75844SAndroid Build Coastguard Worker return pixels_per_frame_upper_limit_; 78*d9f75844SAndroid Build Coastguard Worker } 79*d9f75844SAndroid Build Coastguard Worker frame_rate_upper_limit() const80*d9f75844SAndroid Build Coastguard Workerabsl::optional<double> VideoSourceSinkController::frame_rate_upper_limit() 81*d9f75844SAndroid Build Coastguard Worker const { 82*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 83*d9f75844SAndroid Build Coastguard Worker return frame_rate_upper_limit_; 84*d9f75844SAndroid Build Coastguard Worker } 85*d9f75844SAndroid Build Coastguard Worker rotation_applied() const86*d9f75844SAndroid Build Coastguard Workerbool VideoSourceSinkController::rotation_applied() const { 87*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 88*d9f75844SAndroid Build Coastguard Worker return rotation_applied_; 89*d9f75844SAndroid Build Coastguard Worker } 90*d9f75844SAndroid Build Coastguard Worker resolution_alignment() const91*d9f75844SAndroid Build Coastguard Workerint VideoSourceSinkController::resolution_alignment() const { 92*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 93*d9f75844SAndroid Build Coastguard Worker return resolution_alignment_; 94*d9f75844SAndroid Build Coastguard Worker } 95*d9f75844SAndroid Build Coastguard Worker 96*d9f75844SAndroid Build Coastguard Worker const std::vector<rtc::VideoSinkWants::FrameSize>& resolutions() const97*d9f75844SAndroid Build Coastguard WorkerVideoSourceSinkController::resolutions() const { 98*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 99*d9f75844SAndroid Build Coastguard Worker return resolutions_; 100*d9f75844SAndroid Build Coastguard Worker } 101*d9f75844SAndroid Build Coastguard Worker active() const102*d9f75844SAndroid Build Coastguard Workerbool VideoSourceSinkController::active() const { 103*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 104*d9f75844SAndroid Build Coastguard Worker return active_; 105*d9f75844SAndroid Build Coastguard Worker } 106*d9f75844SAndroid Build Coastguard Worker 107*d9f75844SAndroid Build Coastguard Worker absl::optional<rtc::VideoSinkWants::FrameSize> requested_resolution() const108*d9f75844SAndroid Build Coastguard WorkerVideoSourceSinkController::requested_resolution() const { 109*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 110*d9f75844SAndroid Build Coastguard Worker return requested_resolution_; 111*d9f75844SAndroid Build Coastguard Worker } 112*d9f75844SAndroid Build Coastguard Worker SetRestrictions(VideoSourceRestrictions restrictions)113*d9f75844SAndroid Build Coastguard Workervoid VideoSourceSinkController::SetRestrictions( 114*d9f75844SAndroid Build Coastguard Worker VideoSourceRestrictions restrictions) { 115*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 116*d9f75844SAndroid Build Coastguard Worker restrictions_ = std::move(restrictions); 117*d9f75844SAndroid Build Coastguard Worker } 118*d9f75844SAndroid Build Coastguard Worker SetPixelsPerFrameUpperLimit(absl::optional<size_t> pixels_per_frame_upper_limit)119*d9f75844SAndroid Build Coastguard Workervoid VideoSourceSinkController::SetPixelsPerFrameUpperLimit( 120*d9f75844SAndroid Build Coastguard Worker absl::optional<size_t> pixels_per_frame_upper_limit) { 121*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 122*d9f75844SAndroid Build Coastguard Worker pixels_per_frame_upper_limit_ = std::move(pixels_per_frame_upper_limit); 123*d9f75844SAndroid Build Coastguard Worker } 124*d9f75844SAndroid Build Coastguard Worker SetFrameRateUpperLimit(absl::optional<double> frame_rate_upper_limit)125*d9f75844SAndroid Build Coastguard Workervoid VideoSourceSinkController::SetFrameRateUpperLimit( 126*d9f75844SAndroid Build Coastguard Worker absl::optional<double> frame_rate_upper_limit) { 127*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 128*d9f75844SAndroid Build Coastguard Worker frame_rate_upper_limit_ = std::move(frame_rate_upper_limit); 129*d9f75844SAndroid Build Coastguard Worker } 130*d9f75844SAndroid Build Coastguard Worker SetRotationApplied(bool rotation_applied)131*d9f75844SAndroid Build Coastguard Workervoid VideoSourceSinkController::SetRotationApplied(bool rotation_applied) { 132*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 133*d9f75844SAndroid Build Coastguard Worker rotation_applied_ = rotation_applied; 134*d9f75844SAndroid Build Coastguard Worker } 135*d9f75844SAndroid Build Coastguard Worker SetResolutionAlignment(int resolution_alignment)136*d9f75844SAndroid Build Coastguard Workervoid VideoSourceSinkController::SetResolutionAlignment( 137*d9f75844SAndroid Build Coastguard Worker int resolution_alignment) { 138*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 139*d9f75844SAndroid Build Coastguard Worker resolution_alignment_ = resolution_alignment; 140*d9f75844SAndroid Build Coastguard Worker } 141*d9f75844SAndroid Build Coastguard Worker SetResolutions(std::vector<rtc::VideoSinkWants::FrameSize> resolutions)142*d9f75844SAndroid Build Coastguard Workervoid VideoSourceSinkController::SetResolutions( 143*d9f75844SAndroid Build Coastguard Worker std::vector<rtc::VideoSinkWants::FrameSize> resolutions) { 144*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 145*d9f75844SAndroid Build Coastguard Worker resolutions_ = std::move(resolutions); 146*d9f75844SAndroid Build Coastguard Worker } 147*d9f75844SAndroid Build Coastguard Worker SetActive(bool active)148*d9f75844SAndroid Build Coastguard Workervoid VideoSourceSinkController::SetActive(bool active) { 149*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 150*d9f75844SAndroid Build Coastguard Worker active_ = active; 151*d9f75844SAndroid Build Coastguard Worker } 152*d9f75844SAndroid Build Coastguard Worker SetRequestedResolution(absl::optional<rtc::VideoSinkWants::FrameSize> requested_resolution)153*d9f75844SAndroid Build Coastguard Workervoid VideoSourceSinkController::SetRequestedResolution( 154*d9f75844SAndroid Build Coastguard Worker absl::optional<rtc::VideoSinkWants::FrameSize> requested_resolution) { 155*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_); 156*d9f75844SAndroid Build Coastguard Worker requested_resolution_ = std::move(requested_resolution); 157*d9f75844SAndroid Build Coastguard Worker } 158*d9f75844SAndroid Build Coastguard Worker 159*d9f75844SAndroid Build Coastguard Worker // RTC_EXCLUSIVE_LOCKS_REQUIRED(sequence_checker_) CurrentSettingsToSinkWants() const160*d9f75844SAndroid Build Coastguard Workerrtc::VideoSinkWants VideoSourceSinkController::CurrentSettingsToSinkWants() 161*d9f75844SAndroid Build Coastguard Worker const { 162*d9f75844SAndroid Build Coastguard Worker rtc::VideoSinkWants wants; 163*d9f75844SAndroid Build Coastguard Worker wants.rotation_applied = rotation_applied_; 164*d9f75844SAndroid Build Coastguard Worker // `wants.black_frames` is not used, it always has its default value false. 165*d9f75844SAndroid Build Coastguard Worker wants.max_pixel_count = 166*d9f75844SAndroid Build Coastguard Worker rtc::dchecked_cast<int>(restrictions_.max_pixels_per_frame().value_or( 167*d9f75844SAndroid Build Coastguard Worker std::numeric_limits<int>::max())); 168*d9f75844SAndroid Build Coastguard Worker wants.target_pixel_count = 169*d9f75844SAndroid Build Coastguard Worker restrictions_.target_pixels_per_frame().has_value() 170*d9f75844SAndroid Build Coastguard Worker ? absl::optional<int>(rtc::dchecked_cast<int>( 171*d9f75844SAndroid Build Coastguard Worker restrictions_.target_pixels_per_frame().value())) 172*d9f75844SAndroid Build Coastguard Worker : absl::nullopt; 173*d9f75844SAndroid Build Coastguard Worker wants.max_framerate_fps = 174*d9f75844SAndroid Build Coastguard Worker restrictions_.max_frame_rate().has_value() 175*d9f75844SAndroid Build Coastguard Worker ? static_cast<int>(restrictions_.max_frame_rate().value()) 176*d9f75844SAndroid Build Coastguard Worker : std::numeric_limits<int>::max(); 177*d9f75844SAndroid Build Coastguard Worker wants.resolution_alignment = resolution_alignment_; 178*d9f75844SAndroid Build Coastguard Worker wants.max_pixel_count = 179*d9f75844SAndroid Build Coastguard Worker std::min(wants.max_pixel_count, 180*d9f75844SAndroid Build Coastguard Worker rtc::dchecked_cast<int>(pixels_per_frame_upper_limit_.value_or( 181*d9f75844SAndroid Build Coastguard Worker std::numeric_limits<int>::max()))); 182*d9f75844SAndroid Build Coastguard Worker wants.max_framerate_fps = 183*d9f75844SAndroid Build Coastguard Worker std::min(wants.max_framerate_fps, 184*d9f75844SAndroid Build Coastguard Worker frame_rate_upper_limit_.has_value() 185*d9f75844SAndroid Build Coastguard Worker ? static_cast<int>(frame_rate_upper_limit_.value()) 186*d9f75844SAndroid Build Coastguard Worker : std::numeric_limits<int>::max()); 187*d9f75844SAndroid Build Coastguard Worker wants.resolutions = resolutions_; 188*d9f75844SAndroid Build Coastguard Worker wants.is_active = active_; 189*d9f75844SAndroid Build Coastguard Worker wants.requested_resolution = requested_resolution_; 190*d9f75844SAndroid Build Coastguard Worker return wants; 191*d9f75844SAndroid Build Coastguard Worker } 192*d9f75844SAndroid Build Coastguard Worker 193*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc 194