From 1f53452ca6abd6c32e95715ae830619a1eaa3ab0 Mon Sep 17 00:00:00 2001 From: pbos Date: Fri, 13 May 2016 11:05:35 -0700 Subject: [PATCH] Unify hardware and software QP thresholds. Uses current libvpx (slightly older) thresholds to maintain a larger window of stable QP, but maintains the newer H264 thresholds. BUG= R=glaznev@webrtc.org, mflodman@webrtc.org Review-Url: https://codereview.webrtc.org/1966213002 Cr-Commit-Position: refs/heads/master@{#12734} --- .../api/java/jni/androidmediaencoder_jni.cc | 20 ++++++------------- .../video_coding/codecs/vp8/vp8_impl.cc | 12 +++-------- .../video_coding/utility/quality_scaler.cc | 10 ++++++++++ .../video_coding/utility/quality_scaler.h | 9 +++++++++ 4 files changed, 28 insertions(+), 23 deletions(-) diff --git a/webrtc/api/java/jni/androidmediaencoder_jni.cc b/webrtc/api/java/jni/androidmediaencoder_jni.cc index cffc0d1dce..6a1c581107 100644 --- a/webrtc/api/java/jni/androidmediaencoder_jni.cc +++ b/webrtc/api/java/jni/androidmediaencoder_jni.cc @@ -388,21 +388,13 @@ int32_t MediaCodecVideoEncoder::InitEncode( if (scale_) { if (codecType_ == kVideoCodecVP8) { - // QP is obtained from VP8-bitstream for HW, so the QP corresponds to the - // (internal) range: [0, 127]. And we cannot change QP_max in HW, so it is - // always = 127. Note that in SW, QP is that of the user-level range [0, - // 63]. - const int kLowQpThreshold = 29; - const int kBadQpThreshold = 90; - quality_scaler_.Init(kLowQpThreshold, kBadQpThreshold, - codec_settings->startBitrate, codec_settings->width, - codec_settings->height, - codec_settings->maxFramerate); + quality_scaler_.Init( + QualityScaler::kLowVp8QpThreshold, QualityScaler::kBadVp8QpThreshold, + codec_settings->startBitrate, codec_settings->width, + codec_settings->height, codec_settings->maxFramerate); } else if (codecType_ == kVideoCodecH264) { - // H264 QP is in the range [0, 51]. - const int kLowQpThreshold = 22; - const int kBadQpThreshold = 35; - quality_scaler_.Init(kLowQpThreshold, kBadQpThreshold, + quality_scaler_.Init(QualityScaler::kLowH264QpThreshold, + QualityScaler::kBadH264QpThreshold, codec_settings->startBitrate, codec_settings->width, codec_settings->height, codec_settings->maxFramerate); diff --git a/webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc b/webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc index 15b2f3d105..f035568355 100644 --- a/webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc +++ b/webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc @@ -598,15 +598,9 @@ int VP8EncoderImpl::InitEncode(const VideoCodec* inst, } rps_.Init(); - // QP thresholds are chosen to be high enough to be hit in practice when - // quality is good, but also low enough to not cause a flip-flop behavior - // (e.g. going up in resolution shouldn't give so bad quality that we should - // go back down). - const int kLowQpThreshold = 29; - const int kBadQpThreshold = 100; - quality_scaler_.Init(kLowQpThreshold, kBadQpThreshold, - codec_.startBitrate, codec_.width, codec_.height, - codec_.maxFramerate); + quality_scaler_.Init(QualityScaler::kLowVp8QpThreshold, + QualityScaler::kBadVp8QpThreshold, codec_.startBitrate, + codec_.width, codec_.height, codec_.maxFramerate); // Only apply scaling to improve for single-layer streams. The scaling metrics // use frame drops as a signal and is only applicable when we drop frames. diff --git a/webrtc/modules/video_coding/utility/quality_scaler.cc b/webrtc/modules/video_coding/utility/quality_scaler.cc index c60b50de63..bb60ee036e 100644 --- a/webrtc/modules/video_coding/utility/quality_scaler.cc +++ b/webrtc/modules/video_coding/utility/quality_scaler.cc @@ -30,6 +30,16 @@ static const int kQvgaBitrateThresholdKbps = 250; static const int kQvgaNumPixels = 400 * 300; // 320x240 } // namespace +// QP thresholds are chosen to be high enough to be hit in practice when quality +// is good, but also low enough to not cause a flip-flop behavior (e.g. going up +// in resolution shouldn't give so bad quality that we should go back down). + +const int QualityScaler::kLowVp8QpThreshold = 29; +const int QualityScaler::kBadVp8QpThreshold = 95; + +const int QualityScaler::kLowH264QpThreshold = 22; +const int QualityScaler::kBadH264QpThreshold = 35; + QualityScaler::QualityScaler() : low_qp_threshold_(-1) {} void QualityScaler::Init(int low_qp_threshold, diff --git a/webrtc/modules/video_coding/utility/quality_scaler.h b/webrtc/modules/video_coding/utility/quality_scaler.h index b6d4867be2..fe70393c21 100644 --- a/webrtc/modules/video_coding/utility/quality_scaler.h +++ b/webrtc/modules/video_coding/utility/quality_scaler.h @@ -37,6 +37,15 @@ class QualityScaler { const VideoFrame& GetScaledFrame(const VideoFrame& frame); int downscale_shift() const { return downscale_shift_; } + // QP is obtained from VP8-bitstream for HW, so the QP corresponds to the + // bitstream range of [0, 127] and not the user-level range of [0,63]. + static const int kLowVp8QpThreshold; + static const int kBadVp8QpThreshold; + + // H264 QP is in the range [0, 51]. + static const int kLowH264QpThreshold; + static const int kBadH264QpThreshold; + private: void AdjustScale(bool up); void UpdateTargetResolution(int frame_width, int frame_height);