diff --git a/webrtc/modules/video_coding/utility/quality_scaler.cc b/webrtc/modules/video_coding/utility/quality_scaler.cc index 0e1f1d4248..a5e8c22bb0 100644 --- a/webrtc/modules/video_coding/utility/quality_scaler.cc +++ b/webrtc/modules/video_coding/utility/quality_scaler.cc @@ -18,11 +18,16 @@ static const int kMeasureSecondsFastUpscale = 2; static const int kMeasureSecondsUpscale = 5; static const int kMeasureSecondsDownscale = 5; static const int kFramedropPercentThreshold = 60; -static const int kHdResolutionThreshold = 700 * 500; -static const int kHdBitrateThresholdKbps = 500; // Min width/height to downscale to, set to not go below QVGA, but with some // margin to permit "almost-QVGA" resolutions, such as QCIF. static const int kMinDownscaleDimension = 140; +// Initial resolutions corresponding to a bitrate. Aa bit above their actual +// values to permit near-VGA and near-QVGA resolutions to use the same +// mechanism. +static const int kVgaBitrateThresholdKbps = 500; +static const int kVgaNumPixels = 700 * 500; // 640x480 +static const int kQvgaBitrateThresholdKbps = 250; +static const int kQvgaNumPixels = 400 * 300; // 320x240 } // namespace QualityScaler::QualityScaler() @@ -46,12 +51,13 @@ void QualityScaler::Init(int low_qp_threshold, measure_seconds_upscale_ = kMeasureSecondsFastUpscale; const int init_width = width; const int init_height = height; - // TODO(glaznev): Investigate using thresholds for other resolutions - // or threshold tables. - if (initial_bitrate_kbps > 0 && - initial_bitrate_kbps < kHdBitrateThresholdKbps) { - // Start scaling to roughly VGA. - while (width * height > kHdResolutionThreshold) { + if (initial_bitrate_kbps > 0) { + int init_num_pixels = width * height; + if (initial_bitrate_kbps < kVgaBitrateThresholdKbps) + init_num_pixels = kVgaNumPixels; + if (initial_bitrate_kbps < kQvgaBitrateThresholdKbps) + init_num_pixels = kQvgaNumPixels; + while (width * height > init_num_pixels) { ++downscale_shift_; width /= 2; height /= 2; diff --git a/webrtc/modules/video_coding/utility/quality_scaler_unittest.cc b/webrtc/modules/video_coding/utility/quality_scaler_unittest.cc index 0f761c7d17..58c41ad315 100644 --- a/webrtc/modules/video_coding/utility/quality_scaler_unittest.cc +++ b/webrtc/modules/video_coding/utility/quality_scaler_unittest.cc @@ -16,10 +16,8 @@ namespace webrtc { namespace { static const int kNumSeconds = 10; static const int kWidth = 1920; -static const int kWidthVga = 640; static const int kHalfWidth = kWidth / 2; static const int kHeight = 1080; -static const int kHeightVga = 480; static const int kFramerate = 30; static const int kLowQp = 15; static const int kNormalQp = 30; @@ -380,13 +378,33 @@ TEST_F(QualityScalerTest, DoesNotDownscaleBelow2xDefaultMinDimensionsHeight) { } TEST_F(QualityScalerTest, DownscaleToVgaOnLowInitialBitrate) { - qs_.Init(kLowQpThreshold, kDisabledBadQpThreshold, true, - kLowInitialBitrateKbps, kWidth, kHeight, kFramerate); + static const int kWidth720p = 1280; + static const int kHeight720p = 720; + static const int kInitialBitrateKbps = 300; + input_frame_.CreateEmptyFrame(kWidth720p, kHeight720p, kWidth720p, + kWidth720p / 2, kWidth720p / 2); + qs_.Init(kLowQpThreshold, kDisabledBadQpThreshold, true, kInitialBitrateKbps, + kWidth720p, kHeight720p, kFramerate); qs_.OnEncodeFrame(input_frame_); int init_width = qs_.GetScaledResolution().width; int init_height = qs_.GetScaledResolution().height; - EXPECT_LE(init_width, kWidthVga); - EXPECT_LE(init_height, kHeightVga); + EXPECT_EQ(640, init_width); + EXPECT_EQ(360, init_height); +} + +TEST_F(QualityScalerTest, DownscaleToQvgaOnLowerInitialBitrate) { + static const int kWidth720p = 1280; + static const int kHeight720p = 720; + static const int kInitialBitrateKbps = 200; + input_frame_.CreateEmptyFrame(kWidth720p, kHeight720p, kWidth720p, + kWidth720p / 2, kWidth720p / 2); + qs_.Init(kLowQpThreshold, kDisabledBadQpThreshold, true, kInitialBitrateKbps, + kWidth720p, kHeight720p, kFramerate); + qs_.OnEncodeFrame(input_frame_); + int init_width = qs_.GetScaledResolution().width; + int init_height = qs_.GetScaledResolution().height; + EXPECT_EQ(320, init_width); + EXPECT_EQ(180, init_height); } TEST_F(QualityScalerTest, DownscaleAfterMeasuredSecondsThenSlowerBackUp) {