Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: webrtc/video/vie_encoder.cc

Issue 2698203003: Update sink wants with ranges for both pixel count and frame rate.
Patch Set: Slightly updated sink wants merging in videobroadcaster Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 156
157 void SetSource(rtc::VideoSourceInterface<VideoFrame>* source, 157 void SetSource(rtc::VideoSourceInterface<VideoFrame>* source,
158 const DegradationPreference& degradation_preference) { 158 const DegradationPreference& degradation_preference) {
159 // Called on libjingle's worker thread. 159 // Called on libjingle's worker thread.
160 RTC_DCHECK_CALLED_SEQUENTIALLY(&main_checker_); 160 RTC_DCHECK_CALLED_SEQUENTIALLY(&main_checker_);
161 rtc::VideoSourceInterface<VideoFrame>* old_source = nullptr; 161 rtc::VideoSourceInterface<VideoFrame>* old_source = nullptr;
162 rtc::VideoSinkWants wants; 162 rtc::VideoSinkWants wants;
163 { 163 {
164 rtc::CritScope lock(&crit_); 164 rtc::CritScope lock(&crit_);
165 old_source = source_; 165 old_source = source_;
166 wants = sink_wants_;
167 // If changing degradation preference, clear any constraints from the
168 // current sink wants that will no longer apply.
169 if (degradation_preference_ != degradation_preference) {
170 switch (degradation_preference) {
171 case DegradationPreference::kBalanced:
172 wants.framerate_fps_.reset();
173 break;
174 case DegradationPreference::kMaintainResolution:
175 wants.pixel_count.reset();
176 break;
177 }
178 }
179 degradation_preference_ = degradation_preference;
166 source_ = source; 180 source_ = source;
167 degradation_preference_ = degradation_preference;
168 wants = current_wants();
169 } 181 }
170 182
171 if (old_source != source && old_source != nullptr) { 183 if (old_source != source && old_source != nullptr) {
172 old_source->RemoveSink(vie_encoder_); 184 old_source->RemoveSink(vie_encoder_);
173 } 185 }
174 186
175 if (!source) { 187 if (!source) {
176 return; 188 return;
177 } 189 }
178 190
179 source->AddOrUpdateSink(vie_encoder_, wants); 191 source->AddOrUpdateSink(vie_encoder_, wants);
180 } 192 }
181 193
182 void SetWantsRotationApplied(bool rotation_applied) { 194 void SetWantsRotationApplied(bool rotation_applied) {
183 rtc::CritScope lock(&crit_); 195 rtc::CritScope lock(&crit_);
184 sink_wants_.rotation_applied = rotation_applied; 196 sink_wants_.rotation_applied = rotation_applied;
185 disabled_scaling_sink_wants_.rotation_applied = rotation_applied;
186 if (source_) { 197 if (source_) {
187 source_->AddOrUpdateSink(vie_encoder_, current_wants()); 198 source_->AddOrUpdateSink(vie_encoder_, sink_wants_);
188 } 199 }
189 } 200 }
190 201
191 void RequestResolutionLowerThan(int pixel_count) { 202 void RequestResolutionLowerThan(int pixel_count) {
192 // Called on the encoder task queue. 203 // Called on the encoder task queue.
193 rtc::CritScope lock(&crit_); 204 rtc::CritScope lock(&crit_);
194 if (!IsResolutionScalingEnabledLocked()) { 205 if (!IsResolutionScalingEnabledLocked()) {
195 // This can happen since |degradation_preference_| is set on 206 // This can happen since |degradation_preference_| is set on
196 // libjingle's worker thread but the adaptation is done on the encoder 207 // libjingle's worker thread but the adaptation is done on the encoder
197 // task queue. 208 // task queue.
198 return; 209 return;
199 } 210 }
200 // The input video frame size will have a resolution with less than or 211 // The input video frame size will have a resolution with less than or
201 // equal to |max_pixel_count| depending on how the source can scale the 212 // equal to |max_pixel_count| depending on how the source can scale the
202 // input frame size. 213 // input frame size.
203 const int pixels_wanted = (pixel_count * 3) / 5; 214 const int pixels_wanted = (pixel_count * 3) / 5;
204 if (pixels_wanted < kMinPixelsPerFrame) 215 if (pixels_wanted < kMinPixelsPerFrame)
205 return; 216 return;
206 sink_wants_.max_pixel_count = rtc::Optional<int>(pixels_wanted); 217 sink_wants_.pixel_count.emplace(rtc::VideoSinkWants::Range(
207 sink_wants_.target_pixel_count = rtc::Optional<int>(); 218 kMinPixelsPerFrame, pixels_wanted, pixel_count - 1));
208 if (source_) 219 if (source_)
209 source_->AddOrUpdateSink(vie_encoder_, sink_wants_); 220 source_->AddOrUpdateSink(vie_encoder_, sink_wants_);
210 } 221 }
211 222
223 void RequestFramerateLowerThan(int framerate_fps) {
224 // TODO(sprang): Update SinkWants.
225 }
226
212 void RequestHigherResolutionThan(int pixel_count) { 227 void RequestHigherResolutionThan(int pixel_count) {
213 rtc::CritScope lock(&crit_); 228 rtc::CritScope lock(&crit_);
214 if (!IsResolutionScalingEnabledLocked()) { 229 if (!IsResolutionScalingEnabledLocked()) {
215 // This can happen since |degradation_preference_| is set on 230 // This can happen since |degradation_preference_| is set on
216 // libjingle's worker thread but the adaptation is done on the encoder 231 // libjingle's worker thread but the adaptation is done on the encoder
217 // task queue. 232 // task queue.
218 return; 233 return;
219 } 234 }
220 // On step down we request at most 3/5 the pixel count of the previous 235
221 // resolution, so in order to take "one step up" we request a resolution as 236 // The input video frame size will have a resolution with "one step up"
222 // close as possible to 5/3 of the current resolution. The actual pixel 237 // pixels than |max_pixel_count_step_up| where "one step up" depends on
223 // count selected depends on the capabilities of the source. In order to not 238 // how the source can scale the input frame size. We still cap the step up
224 // take a too large step up, we cap the requested pixel count to be at most 239 // to be at most twice the number of pixels.
225 // four time the current number of pixels. 240 sink_wants_.pixel_count.emplace(rtc::VideoSinkWants::Range(
226 sink_wants_.target_pixel_count = rtc::Optional<int>((pixel_count * 5) / 3); 241 pixel_count + 1, (pixel_count * 5) / 3, pixel_count * 4));
227 sink_wants_.max_pixel_count = rtc::Optional<int>(pixel_count * 4);
228 if (source_) 242 if (source_)
229 source_->AddOrUpdateSink(vie_encoder_, sink_wants_); 243 source_->AddOrUpdateSink(vie_encoder_, sink_wants_);
230 } 244 }
231 245
246 void RequestHigherFramerateThan(int framerate_fps) {
247 // TODO(sprang): Update SinkWants.
248 }
249
232 private: 250 private:
233 bool IsResolutionScalingEnabledLocked() const 251 bool IsResolutionScalingEnabledLocked() const
234 EXCLUSIVE_LOCKS_REQUIRED(&crit_) { 252 EXCLUSIVE_LOCKS_REQUIRED(&crit_) {
235 return degradation_preference_ != 253 return degradation_preference_ !=
236 DegradationPreference::kMaintainResolution; 254 DegradationPreference::kMaintainResolution;
237 } 255 }
238 256
239 const rtc::VideoSinkWants& current_wants() const 257 bool IsFramerateScalingEnabledLocked() const
240 EXCLUSIVE_LOCKS_REQUIRED(&crit_) { 258 EXCLUSIVE_LOCKS_REQUIRED(&crit_) {
241 return IsResolutionScalingEnabledLocked() ? sink_wants_ 259 return degradation_preference_ ==
242 : disabled_scaling_sink_wants_; 260 DegradationPreference::kMaintainResolution;
243 } 261 }
244 262
245 rtc::CriticalSection crit_; 263 rtc::CriticalSection crit_;
246 rtc::SequencedTaskChecker main_checker_; 264 rtc::SequencedTaskChecker main_checker_;
247 ViEEncoder* const vie_encoder_; 265 ViEEncoder* const vie_encoder_;
248 rtc::VideoSinkWants sink_wants_ GUARDED_BY(&crit_); 266 rtc::VideoSinkWants sink_wants_ GUARDED_BY(&crit_);
249 rtc::VideoSinkWants disabled_scaling_sink_wants_ GUARDED_BY(&crit_);
250 DegradationPreference degradation_preference_ GUARDED_BY(&crit_); 267 DegradationPreference degradation_preference_ GUARDED_BY(&crit_);
251 rtc::VideoSourceInterface<VideoFrame>* source_ GUARDED_BY(&crit_); 268 rtc::VideoSourceInterface<VideoFrame>* source_ GUARDED_BY(&crit_);
252 269
253 RTC_DISALLOW_COPY_AND_ASSIGN(VideoSourceProxy); 270 RTC_DISALLOW_COPY_AND_ASSIGN(VideoSourceProxy);
254 }; 271 };
255 272
256 ViEEncoder::ViEEncoder(uint32_t number_of_cores, 273 ViEEncoder::ViEEncoder(uint32_t number_of_cores,
257 SendStatisticsProxy* stats_proxy, 274 SendStatisticsProxy* stats_proxy,
258 const VideoSendStream::Config::EncoderSettings& settings, 275 const VideoSendStream::Config::EncoderSettings& settings,
259 rtc::VideoSinkInterface<VideoFrame>* pre_encode_callback, 276 rtc::VideoSinkInterface<VideoFrame>* pre_encode_callback,
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 751
735 if (video_suspension_changed) { 752 if (video_suspension_changed) {
736 LOG(LS_INFO) << "Video suspend state changed to: " 753 LOG(LS_INFO) << "Video suspend state changed to: "
737 << (video_is_suspended ? "suspended" : "not suspended"); 754 << (video_is_suspended ? "suspended" : "not suspended");
738 stats_proxy_->OnSuspendChange(video_is_suspended); 755 stats_proxy_->OnSuspendChange(video_is_suspended);
739 } 756 }
740 } 757 }
741 758
742 void ViEEncoder::AdaptDown(AdaptReason reason) { 759 void ViEEncoder::AdaptDown(AdaptReason reason) {
743 RTC_DCHECK_RUN_ON(&encoder_queue_); 760 RTC_DCHECK_RUN_ON(&encoder_queue_);
744 if (degradation_preference_ != DegradationPreference::kBalanced) 761 AdaptationRequest adaptation_request = {
745 return; 762 last_frame_info_->pixel_count(),
746 RTC_DCHECK(static_cast<bool>(last_frame_info_)); 763 stats_proxy_->GetStats().input_frame_rate,
747 int current_pixel_count = last_frame_info_->pixel_count(); 764 AdaptationRequest::Mode::kAdaptDown};
765
748 if (last_adaptation_request_ && 766 if (last_adaptation_request_ &&
749 last_adaptation_request_->mode_ == AdaptationRequest::Mode::kAdaptDown && 767 last_adaptation_request_->mode_ == AdaptationRequest::Mode::kAdaptDown) {
750 current_pixel_count >= last_adaptation_request_->input_pixel_count_) { 768 switch (degradation_preference_) {
751 // Don't request lower resolution if the current resolution is not lower 769 case DegradationPreference::kBalanced:
752 // than the last time we asked for the resolution to be lowered. 770 if (adaptation_request.input_pixel_count_ >=
753 return; 771 last_adaptation_request_->input_pixel_count_) {
772 // Don't request lower resolution if the current resolution is not
773 // lower
774 // than the last time we asked for the resolution to be lowered.
775 return;
776 }
777 break;
778 case DegradationPreference::kMaintainResolution:
779 if (adaptation_request.framerate_fps_ <= 1) {
780 // Don't request lower framerate if we don't have a valid frame rate.
781 // Since framerate, unlike resolution, is a measure we have to
782 // estimate, and can fluctuate naturally over time, don't make the
783 // same kind of limitations as for resolution, but trust the overuse
784 // detector to not trigger too often.
785 return;
786 }
787 break;
788 }
754 } 789 }
755 last_adaptation_request_.emplace(AdaptationRequest{ 790
756 current_pixel_count, AdaptationRequest::Mode::kAdaptDown}); 791 last_adaptation_request_.emplace(adaptation_request);
757 792
758 switch (reason) { 793 switch (reason) {
759 case kQuality: 794 case kQuality:
760 stats_proxy_->OnQualityRestrictedResolutionChanged( 795 stats_proxy_->OnQualityRestrictedResolutionChanged(
761 scale_counter_[reason] + 1); 796 scale_counter_[reason] + 1);
762 break; 797 break;
763 case kCpu: 798 case kCpu:
764 if (scale_counter_[reason] >= kMaxCpuDowngrades) 799 if (scale_counter_[reason] >= kMaxCpuDowngrades)
765 return; 800 return;
766 // Update stats accordingly. 801 // Update stats accordingly.
767 stats_proxy_->OnCpuRestrictedResolutionChanged(true); 802 stats_proxy_->OnCpuRestrictedResolutionChanged(true);
768 break; 803 break;
769 } 804 }
770 ++scale_counter_[reason]; 805 ++scale_counter_[reason];
771 source_proxy_->RequestResolutionLowerThan(current_pixel_count); 806
772 LOG(LS_INFO) << "Scaling down resolution."; 807 switch (degradation_preference_) {
808 case DegradationPreference::kBalanced:
809 source_proxy_->RequestResolutionLowerThan(
810 adaptation_request.input_pixel_count_);
811 LOG(LS_INFO) << "Scaling down resolution.";
812 break;
813 case DegradationPreference::kMaintainResolution:
814 source_proxy_->RequestFramerateLowerThan(
815 adaptation_request.framerate_fps_);
816 LOG(LS_INFO) << "Scaling down framerate.";
817 break;
818 }
819
773 for (size_t i = 0; i < kScaleReasonSize; ++i) { 820 for (size_t i = 0; i < kScaleReasonSize; ++i) {
774 LOG(LS_INFO) << "Scaled " << scale_counter_[i] 821 LOG(LS_INFO) << "Scaled " << scale_counter_[i]
775 << " times for reason: " << (i ? "cpu" : "quality"); 822 << " times for reason: " << (i ? "cpu" : "quality");
776 } 823 }
777 } 824 }
778 825
779 void ViEEncoder::AdaptUp(AdaptReason reason) { 826 void ViEEncoder::AdaptUp(AdaptReason reason) {
780 RTC_DCHECK_RUN_ON(&encoder_queue_); 827 RTC_DCHECK_RUN_ON(&encoder_queue_);
781 if (scale_counter_[reason] == 0 || 828 if (scale_counter_[reason] == 0 ||
782 degradation_preference_ != DegradationPreference::kBalanced) { 829 degradation_preference_ != DegradationPreference::kBalanced) {
783 return; 830 return;
784 } 831 }
785 // Only scale if resolution is higher than last time we requested higher 832
786 // resolution. 833 AdaptationRequest adaptation_request = {
787 RTC_DCHECK(static_cast<bool>(last_frame_info_)); 834 last_frame_info_->pixel_count(),
788 int current_pixel_count = last_frame_info_->pixel_count(); 835 stats_proxy_->GetStats().input_frame_rate,
836 AdaptationRequest::Mode::kAdaptUp};
837
789 if (last_adaptation_request_ && 838 if (last_adaptation_request_ &&
790 last_adaptation_request_->mode_ == AdaptationRequest::Mode::kAdaptUp && 839 last_adaptation_request_->mode_ == AdaptationRequest::Mode::kAdaptUp) {
791 current_pixel_count <= last_adaptation_request_->input_pixel_count_) { 840 switch (degradation_preference_) {
792 // Don't request higher resolution if the current resolution is not higher 841 case DegradationPreference::kBalanced:
793 // than the last time we asked for the resolution to be higher. 842 if (adaptation_request.input_pixel_count_ <=
794 return; 843 last_adaptation_request_->input_pixel_count_) {
844 // Don't request higher resolution if the current resolution is not
845 // higher than the last time we asked for the resolution to be higher.
846 return;
847 }
848 break;
849 case DegradationPreference::kMaintainResolution:
850 // TODO(sprang): Don't request higher framerate if we are already at
851 // max requested fps?
852 break;
853 }
795 } 854 }
796 last_adaptation_request_.emplace(AdaptationRequest{ 855
797 current_pixel_count, AdaptationRequest::Mode::kAdaptUp}); 856 last_adaptation_request_.emplace(adaptation_request);
798 857
799 switch (reason) { 858 switch (reason) {
800 case kQuality: 859 case kQuality:
801 stats_proxy_->OnQualityRestrictedResolutionChanged( 860 stats_proxy_->OnQualityRestrictedResolutionChanged(
802 scale_counter_[reason] - 1); 861 scale_counter_[reason] - 1);
803 break; 862 break;
804 case kCpu: 863 case kCpu:
805 // Update stats accordingly. 864 // Update stats accordingly.
806 stats_proxy_->OnCpuRestrictedResolutionChanged(scale_counter_[reason] > 865 stats_proxy_->OnCpuRestrictedResolutionChanged(scale_counter_[reason] >
807 1); 866 1);
808 break; 867 break;
809 } 868 }
810 --scale_counter_[reason]; 869 --scale_counter_[reason];
811 source_proxy_->RequestHigherResolutionThan(current_pixel_count); 870
812 LOG(LS_INFO) << "Scaling up resolution."; 871 switch (degradation_preference_) {
872 case DegradationPreference::kBalanced:
873 source_proxy_->RequestHigherResolutionThan(
874 adaptation_request.input_pixel_count_);
875 LOG(LS_INFO) << "Scaling up resolution.";
876 break;
877 case DegradationPreference::kMaintainResolution:
878 source_proxy_->RequestHigherFramerateThan(
879 adaptation_request.framerate_fps_);
880 LOG(LS_INFO) << "Scaling up framerate.";
881 break;
882 }
883
813 for (size_t i = 0; i < kScaleReasonSize; ++i) { 884 for (size_t i = 0; i < kScaleReasonSize; ++i) {
814 LOG(LS_INFO) << "Scaled " << scale_counter_[i] 885 LOG(LS_INFO) << "Scaled " << scale_counter_[i]
815 << " times for reason: " << (i ? "cpu" : "quality"); 886 << " times for reason: " << (i ? "cpu" : "quality");
816 } 887 }
817 } 888 }
818 889
819 } // namespace webrtc 890 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698