From 926dfcdf5e72081ac76e19554ae2af7c2f0537d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Bostr=C3=B6m?= Date: Thu, 14 Apr 2016 14:48:10 +0200 Subject: [PATCH] Make QualityScaler not downscale below QVGA. Applies to all platforms, not only Android now, 160x90 video looks awful and there's no real point to going below QVGA. BUG=webrtc:5678 R=danilchap@webrtc.org TBR=glaznev@webrtc.org Review URL: https://codereview.webrtc.org/1867643003 . Cr-Commit-Position: refs/heads/master@{#12362} --- .../api/java/jni/androidmediaencoder_jni.cc | 6 +-- .../video_coding/utility/quality_scaler.cc | 22 ++++------- .../video_coding/utility/quality_scaler.h | 4 -- .../utility/quality_scaler_unittest.cc | 39 ++++++------------- 4 files changed, 22 insertions(+), 49 deletions(-) diff --git a/webrtc/api/java/jni/androidmediaencoder_jni.cc b/webrtc/api/java/jni/androidmediaencoder_jni.cc index 593554e5e0..d9d7a809b8 100644 --- a/webrtc/api/java/jni/androidmediaencoder_jni.cc +++ b/webrtc/api/java/jni/androidmediaencoder_jni.cc @@ -352,7 +352,6 @@ int32_t MediaCodecVideoEncoder::InitEncode( const webrtc::VideoCodec* codec_settings, int32_t /* number_of_cores */, size_t /* max_payload_size */) { - const int kMinDimension = 180; if (codec_settings == NULL) { ALOGE << "NULL VideoCodec instance"; return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; @@ -396,10 +395,9 @@ int32_t MediaCodecVideoEncoder::InitEncode( RTC_NOTREACHED() << "Unsupported codec without configured QP thresholds."; scale_ = false; } - quality_scaler_.SetMinResolution(kMinDimension, kMinDimension); QualityScaler::Resolution res = quality_scaler_.GetScaledResolution(); - init_width = std::max(res.width, kMinDimension); - init_height = std::max(res.height, kMinDimension); + init_width = res.width; + init_height = res.height; ALOGD << "Scaled resolution: " << init_width << " x " << init_height; } diff --git a/webrtc/modules/video_coding/utility/quality_scaler.cc b/webrtc/modules/video_coding/utility/quality_scaler.cc index c6e5669731..c6a6ba2ea5 100644 --- a/webrtc/modules/video_coding/utility/quality_scaler.cc +++ b/webrtc/modules/video_coding/utility/quality_scaler.cc @@ -11,6 +11,7 @@ namespace webrtc { +namespace { static const int kMinFps = 5; static const int kMeasureSecondsDownscale = 3; // Threshold constant used until first downscale (to permit fast rampup). @@ -19,17 +20,15 @@ static const int kMeasureSecondsUpscale = 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; +} // namespace const int QualityScaler::kDefaultLowQpDenominator = 3; -// Note that this is the same for width and height to permit 120x90 in both -// portrait and landscape mode. -const int QualityScaler::kDefaultMinDownscaleDimension = 90; QualityScaler::QualityScaler() - : low_qp_threshold_(-1), - framerate_down_(false), - min_width_(kDefaultMinDownscaleDimension), - min_height_(kDefaultMinDownscaleDimension) {} + : low_qp_threshold_(-1), framerate_down_(false) {} void QualityScaler::Init(int low_qp_threshold, int high_qp_threshold, @@ -65,11 +64,6 @@ void QualityScaler::Init(int low_qp_threshold, target_framerate_ = -1; } -void QualityScaler::SetMinResolution(int min_width, int min_height) { - min_width_ = min_width; - min_height_ = min_height; -} - // Report framerate(fps) to estimate # of samples. void QualityScaler::ReportFramerate(int framerate) { framerate_ = framerate; @@ -158,8 +152,8 @@ void QualityScaler::UpdateTargetResolution(int frame_width, int frame_height) { res_.width = frame_width; res_.height = frame_height; for (int shift = downscale_shift_; - shift > 0 && (res_.width / 2 >= min_width_) && - (res_.height / 2 >= min_height_); + shift > 0 && (res_.width / 2 >= kMinDownscaleDimension) && + (res_.height / 2 >= kMinDownscaleDimension); --shift) { res_.width /= 2; res_.height /= 2; diff --git a/webrtc/modules/video_coding/utility/quality_scaler.h b/webrtc/modules/video_coding/utility/quality_scaler.h index 34dda0e9f3..1720107b90 100644 --- a/webrtc/modules/video_coding/utility/quality_scaler.h +++ b/webrtc/modules/video_coding/utility/quality_scaler.h @@ -18,7 +18,6 @@ namespace webrtc { class QualityScaler { public: static const int kDefaultLowQpDenominator; - static const int kDefaultMinDownscaleDimension; struct Resolution { int width; int height; @@ -32,7 +31,6 @@ class QualityScaler { int width, int height, int fps); - void SetMinResolution(int min_width, int min_height); void ReportFramerate(int framerate); void ReportQP(int qp); void ReportDroppedFrame(); @@ -68,8 +66,6 @@ class QualityScaler { int downscale_shift_; int framerate_down_; bool use_framerate_reduction_; - int min_width_; - int min_height_; }; } // namespace webrtc diff --git a/webrtc/modules/video_coding/utility/quality_scaler_unittest.cc b/webrtc/modules/video_coding/utility/quality_scaler_unittest.cc index 72e9db405e..3c8ac75d4b 100644 --- a/webrtc/modules/video_coding/utility/quality_scaler_unittest.cc +++ b/webrtc/modules/video_coding/utility/quality_scaler_unittest.cc @@ -32,6 +32,7 @@ static const int kLowInitialBitrateKbps = 300; static const int kMeasureSecondsDownscale = 3; static const int kMeasureSecondsFastUpscale = 2; static const int kMeasureSecondsUpscale = 5; +static const int kMinDownscaleDimension = 140; } // namespace class QualityScalerTest : public ::testing::Test { @@ -200,7 +201,7 @@ void QualityScalerTest::ContinuouslyDownscalesByHalfDimensionsAndBackUp() { int min_dimension = initial_min_dimension; int current_shift = 0; // Drop all frames to force-trigger downscaling. - while (min_dimension >= 2 * QualityScaler::kDefaultMinDownscaleDimension) { + while (min_dimension >= 2 * kMinDownscaleDimension) { EXPECT_TRUE(TriggerScale(kScaleDown)) << "No downscale within " << kNumSeconds << " seconds."; qs_.OnEncodeFrame(input_frame_); @@ -371,12 +372,12 @@ TEST_F(QualityScalerTest, ChangeSpatialSizeOnly) { TEST_F(QualityScalerTest, DoesNotDownscaleBelow2xDefaultMinDimensionsWidth) { DoesNotDownscaleFrameDimensions( - 2 * QualityScaler::kDefaultMinDownscaleDimension - 1, 1000); + 2 * kMinDownscaleDimension - 1, 1000); } TEST_F(QualityScalerTest, DoesNotDownscaleBelow2xDefaultMinDimensionsHeight) { DoesNotDownscaleFrameDimensions( - 1000, 2 * QualityScaler::kDefaultMinDownscaleDimension - 1); + 1000, 2 * kMinDownscaleDimension - 1); } TEST_F(QualityScalerTest, DownscaleToVgaOnLowInitialBitrate) { @@ -480,36 +481,20 @@ void QualityScalerTest::DownscaleEndsAt(int input_width, } } -TEST_F(QualityScalerTest, DefaultDownscalesTo160x90) { - DownscaleEndsAt(320, 180, 160, 90); +TEST_F(QualityScalerTest, DownscalesTo320x180) { + DownscaleEndsAt(640, 360, 320, 180); } -TEST_F(QualityScalerTest, DefaultDownscalesTo90x160) { - DownscaleEndsAt(180, 320, 90, 160); +TEST_F(QualityScalerTest, DownscalesTo180x320) { + DownscaleEndsAt(360, 640, 180, 320); } -TEST_F(QualityScalerTest, DefaultDownscalesFrom1280x720To160x90) { - DownscaleEndsAt(1280, 720, 160, 90); +TEST_F(QualityScalerTest, DownscalesFrom1280x720To320x180) { + DownscaleEndsAt(1280, 720, 320, 180); } -TEST_F(QualityScalerTest, DefaultDoesntDownscaleBelow160x90) { - DownscaleEndsAt(320 - 1, 180 - 1, 320 - 1, 180 - 1); -} - -TEST_F(QualityScalerTest, DefaultDoesntDownscaleBelow90x160) { - DownscaleEndsAt(180 - 1, 320 - 1, 180 - 1, 320 - 1); -} - -TEST_F(QualityScalerTest, RespectsMinResolutionWidth) { - // Should end at 200x100, as width can't go lower. - qs_.SetMinResolution(200, 10); - DownscaleEndsAt(1600, 800, 200, 100); -} - -TEST_F(QualityScalerTest, RespectsMinResolutionHeight) { - // Should end at 100x200, as height can't go lower. - qs_.SetMinResolution(10, 200); - DownscaleEndsAt(800, 1600, 100, 200); +TEST_F(QualityScalerTest, DoesntDownscaleInitialQvga) { + DownscaleEndsAt(320, 180, 320, 180); } } // namespace webrtc