Index: webrtc/video/vie_encoder.cc |
diff --git a/webrtc/video/vie_encoder.cc b/webrtc/video/vie_encoder.cc |
index b56bbf5153852af7c67e70fff1395ef52677639d..203d1c405a8813d05b627cd464803bb9df39f645 100644 |
--- a/webrtc/video/vie_encoder.cc |
+++ b/webrtc/video/vie_encoder.cc |
@@ -230,54 +230,50 @@ class ViEEncoder::VideoSourceProxy { |
bool RequestResolutionLowerThan(int pixel_count) { |
// Called on the encoder task queue. |
rtc::CritScope lock(&crit_); |
- if (!IsResolutionScalingEnabled(degradation_preference_)) { |
+ if (!source_ || !IsResolutionScalingEnabled(degradation_preference_)) { |
// This can happen since |degradation_preference_| is set on libjingle's |
// worker thread but the adaptation is done on the encoder task queue. |
return false; |
} |
- // The input video frame size will have a resolution with less than or |
- // equal to |max_pixel_count| depending on how the source can scale the |
- // input frame size. |
+ // The input video frame size will have a resolution less than or equal to |
+ // |max_pixel_count| depending on how the source can scale the frame size. |
const int pixels_wanted = (pixel_count * 3) / 5; |
- if (pixels_wanted < kMinPixelsPerFrame) |
+ if (pixels_wanted < kMinPixelsPerFrame || |
+ pixels_wanted >= sink_wants_.max_pixel_count) { |
return false; |
- |
+ } |
+ LOG(LS_INFO) << "Scaling down resolution, max pixels: " << pixels_wanted; |
sink_wants_.max_pixel_count = pixels_wanted; |
sink_wants_.target_pixel_count = rtc::Optional<int>(); |
- if (source_) |
- source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants()); |
+ source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants()); |
return true; |
} |
- void RequestFramerateLowerThan(int framerate_fps) { |
+ bool RequestFramerateLowerThan(int fps) { |
// Called on the encoder task queue. |
- rtc::CritScope lock(&crit_); |
- if (!IsFramerateScalingEnabled(degradation_preference_)) { |
- // This can happen since |degradation_preference_| is set on libjingle's |
- // worker thread but the adaptation is done on the encoder task queue. |
- return; |
- } |
- // The input video frame rate will be scaled down to 2/3 of input fps, |
- // rounding down. |
- const int framerate_wanted = |
- std::max(kMinFramerateFps, (framerate_fps * 2) / 3); |
- sink_wants_.max_framerate_fps = framerate_wanted; |
- if (source_) |
- source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants()); |
+ // The input video frame rate will be scaled down to 2/3, rounding down. |
+ return RestrictFramerate((fps * 2) / 3); |
} |
- void RequestHigherResolutionThan(int pixel_count) { |
+ bool RequestHigherResolutionThan(int pixel_count) { |
+ // Called on the encoder task queue. |
rtc::CritScope lock(&crit_); |
- if (!IsResolutionScalingEnabled(degradation_preference_)) { |
+ if (!source_ || !IsResolutionScalingEnabled(degradation_preference_)) { |
// This can happen since |degradation_preference_| is set on libjingle's |
// worker thread but the adaptation is done on the encoder task queue. |
- return; |
+ return false; |
} |
+ int max_pixels_wanted = pixel_count; |
+ if (max_pixels_wanted != std::numeric_limits<int>::max()) |
+ max_pixels_wanted = pixel_count * 4; |
+ |
+ if (max_pixels_wanted <= sink_wants_.max_pixel_count) |
+ return false; |
- if (pixel_count == std::numeric_limits<int>::max()) { |
+ sink_wants_.max_pixel_count = max_pixels_wanted; |
+ if (max_pixels_wanted == std::numeric_limits<int>::max()) { |
// Remove any constraints. |
sink_wants_.target_pixel_count.reset(); |
- sink_wants_.max_pixel_count = std::numeric_limits<int>::max(); |
} else { |
// On step down we request at most 3/5 the pixel count of the previous |
// resolution, so in order to take "one step up" we request a resolution |
@@ -287,31 +283,52 @@ class ViEEncoder::VideoSourceProxy { |
// most four time the current number of pixels. |
sink_wants_.target_pixel_count = |
rtc::Optional<int>((pixel_count * 5) / 3); |
- sink_wants_.max_pixel_count = pixel_count * 4; |
} |
- if (source_) |
- source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants()); |
+ LOG(LS_INFO) << "Scaling up resolution, max pixels: " << max_pixels_wanted; |
+ source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants()); |
+ return true; |
+ } |
+ |
+ bool RequestHigherFramerateThan(int fps) { |
+ // Called on the encoder task queue. |
+ // The input frame rate will be scaled up to the last step, with rounding. |
+ int framerate_wanted = fps; |
+ if (fps != std::numeric_limits<int>::max()) |
+ framerate_wanted = (fps * 3) / 2; |
+ |
+ return IncreaseFramerate(framerate_wanted); |
} |
- void RequestHigherFramerateThan(int framerate_fps) { |
+ bool RestrictFramerate(int fps) { |
// Called on the encoder task queue. |
rtc::CritScope lock(&crit_); |
- if (!IsFramerateScalingEnabled(degradation_preference_)) { |
- // This can happen since |degradation_preference_| is set on libjingle's |
- // worker thread but the adaptation is done on the encoder task queue. |
- return; |
- } |
- if (framerate_fps == std::numeric_limits<int>::max()) { |
- // Remove any restrains. |
- sink_wants_.max_framerate_fps = std::numeric_limits<int>::max(); |
- } else { |
- // The input video frame rate will be scaled up to the last step, with |
- // rounding. |
- const int framerate_wanted = (framerate_fps * 3) / 2; |
- sink_wants_.max_framerate_fps = framerate_wanted; |
- } |
- if (source_) |
- source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants()); |
+ if (!source_ || !IsFramerateScalingEnabled(degradation_preference_)) |
+ return false; |
+ |
+ const int fps_wanted = std::max(kMinFramerateFps, fps); |
+ if (fps_wanted >= sink_wants_.max_framerate_fps) |
+ return false; |
+ |
+ LOG(LS_INFO) << "Scaling down framerate: " << fps_wanted; |
+ sink_wants_.max_framerate_fps = fps_wanted; |
+ source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants()); |
+ return true; |
+ } |
+ |
+ bool IncreaseFramerate(int fps) { |
+ // Called on the encoder task queue. |
+ rtc::CritScope lock(&crit_); |
+ if (!source_ || !IsFramerateScalingEnabled(degradation_preference_)) |
+ return false; |
+ |
+ const int fps_wanted = std::max(kMinFramerateFps, fps); |
+ if (fps_wanted <= sink_wants_.max_framerate_fps) |
+ return false; |
+ |
+ LOG(LS_INFO) << "Scaling up framerate: " << fps_wanted; |
+ sink_wants_.max_framerate_fps = fps_wanted; |
+ source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants()); |
+ return true; |
} |
private: |
@@ -827,17 +844,19 @@ void ViEEncoder::AdaptDown(AdaptReason reason) { |
case VideoSendStream::DegradationPreference::kBalanced: |
FALLTHROUGH(); |
case VideoSendStream::DegradationPreference::kMaintainFramerate: |
+ // Scale down resolution. |
if (!source_proxy_->RequestResolutionLowerThan( |
adaptation_request.input_pixel_count_)) { |
return; |
} |
- LOG(LS_INFO) << "Scaling down resolution."; |
GetAdaptCounter().IncrementResolution(reason, 1); |
break; |
case VideoSendStream::DegradationPreference::kMaintainResolution: |
- source_proxy_->RequestFramerateLowerThan( |
- adaptation_request.framerate_fps_); |
- LOG(LS_INFO) << "Scaling down framerate."; |
+ // Scale down framerate. |
+ if (!source_proxy_->RequestFramerateLowerThan( |
+ adaptation_request.framerate_fps_)) { |
+ return; |
+ } |
GetAdaptCounter().IncrementFramerate(reason, 1); |
break; |
case VideoSendStream::DegradationPreference::kDegradationDisabled: |
@@ -892,30 +911,30 @@ void ViEEncoder::AdaptUp(AdaptReason reason) { |
switch (degradation_preference_) { |
case VideoSendStream::DegradationPreference::kBalanced: |
FALLTHROUGH(); |
- case VideoSendStream::DegradationPreference::kMaintainFramerate: |
- if (adapt_counter.TotalCount() == 1) { |
+ case VideoSendStream::DegradationPreference::kMaintainFramerate: { |
+ // Scale up resolution. |
+ int pixel_count = adaptation_request.input_pixel_count_; |
+ if (adapt_counter.ResolutionCount() == 1) { |
LOG(LS_INFO) << "Removing resolution down-scaling setting."; |
- source_proxy_->RequestHigherResolutionThan( |
- std::numeric_limits<int>::max()); |
- } else { |
- source_proxy_->RequestHigherResolutionThan( |
- adaptation_request.input_pixel_count_); |
- LOG(LS_INFO) << "Scaling up resolution."; |
+ pixel_count = std::numeric_limits<int>::max(); |
} |
+ if (!source_proxy_->RequestHigherResolutionThan(pixel_count)) |
+ return; |
GetAdaptCounter().IncrementResolution(reason, -1); |
break; |
- case VideoSendStream::DegradationPreference::kMaintainResolution: |
- if (adapt_counter.TotalCount() == 1) { |
+ } |
+ case VideoSendStream::DegradationPreference::kMaintainResolution: { |
+ // Scale up framerate. |
+ int fps = adaptation_request.framerate_fps_; |
+ if (adapt_counter.FramerateCount() == 1) { |
LOG(LS_INFO) << "Removing framerate down-scaling setting."; |
- source_proxy_->RequestHigherFramerateThan( |
- std::numeric_limits<int>::max()); |
- } else { |
- source_proxy_->RequestHigherFramerateThan( |
- adaptation_request.framerate_fps_); |
- LOG(LS_INFO) << "Scaling up framerate."; |
+ fps = std::numeric_limits<int>::max(); |
} |
+ if (!source_proxy_->RequestHigherFramerateThan(fps)) |
+ return; |
GetAdaptCounter().IncrementFramerate(reason, -1); |
break; |
+ } |
case VideoSendStream::DegradationPreference::kDegradationDisabled: |
RTC_NOTREACHED(); |
} |