Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2014 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 | |
| 11 // TODO(nisse): Switch to RTC_CHECK (or RTC_DCHECK) ? | |
|
pbos-webrtc
2016/05/31 14:14:02
Do that now, please. Pref DCHECK. :)
nisse-webrtc
2016/06/01 09:15:18
Done.
| |
| 12 #include <assert.h> | |
| 13 | |
| 10 #include "webrtc/modules/video_coding/utility/quality_scaler.h" | 14 #include "webrtc/modules/video_coding/utility/quality_scaler.h" |
| 11 | 15 |
| 12 namespace webrtc { | 16 namespace webrtc { |
| 13 | 17 |
| 14 namespace { | 18 namespace { |
| 15 static const int kMinFps = 5; | 19 static const int kMinFps = 5; |
| 16 // Threshold constant used until first downscale (to permit fast rampup). | 20 // Threshold constant used until first downscale (to permit fast rampup). |
| 17 static const int kMeasureSecondsFastUpscale = 2; | 21 static const int kMeasureSecondsFastUpscale = 2; |
| 18 static const int kMeasureSecondsUpscale = 5; | 22 static const int kMeasureSecondsUpscale = 5; |
| 19 static const int kMeasureSecondsDownscale = 5; | 23 static const int kMeasureSecondsDownscale = 5; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 87 void QualityScaler::ReportQP(int qp) { | 91 void QualityScaler::ReportQP(int qp) { |
| 88 framedrop_percent_.AddSample(0); | 92 framedrop_percent_.AddSample(0); |
| 89 average_qp_downscale_.AddSample(qp); | 93 average_qp_downscale_.AddSample(qp); |
| 90 average_qp_upscale_.AddSample(qp); | 94 average_qp_upscale_.AddSample(qp); |
| 91 } | 95 } |
| 92 | 96 |
| 93 void QualityScaler::ReportDroppedFrame() { | 97 void QualityScaler::ReportDroppedFrame() { |
| 94 framedrop_percent_.AddSample(100); | 98 framedrop_percent_.AddSample(100); |
| 95 } | 99 } |
| 96 | 100 |
| 97 void QualityScaler::OnEncodeFrame(const VideoFrame& frame) { | 101 void QualityScaler::OnEncodeFrame(int width, int height) { |
| 98 // Should be set through InitEncode -> Should be set by now. | 102 // Should be set through InitEncode -> Should be set by now. |
| 99 assert(low_qp_threshold_ >= 0); | 103 assert(low_qp_threshold_ >= 0); |
| 100 assert(num_samples_upscale_ > 0); | 104 assert(num_samples_upscale_ > 0); |
| 101 assert(num_samples_downscale_ > 0); | 105 assert(num_samples_downscale_ > 0); |
| 102 | 106 |
| 103 // Update scale factor. | 107 // Update scale factor. |
| 104 int avg_drop = 0; | 108 int avg_drop = 0; |
| 105 int avg_qp = 0; | 109 int avg_qp = 0; |
| 106 | 110 |
| 107 if ((framedrop_percent_.GetAverage(num_samples_downscale_, &avg_drop) && | 111 if ((framedrop_percent_.GetAverage(num_samples_downscale_, &avg_drop) && |
| 108 avg_drop >= kFramedropPercentThreshold) || | 112 avg_drop >= kFramedropPercentThreshold) || |
| 109 (average_qp_downscale_.GetAverage(num_samples_downscale_, &avg_qp) && | 113 (average_qp_downscale_.GetAverage(num_samples_downscale_, &avg_qp) && |
| 110 avg_qp > high_qp_threshold_)) { | 114 avg_qp > high_qp_threshold_)) { |
| 111 AdjustScale(false); | 115 AdjustScale(false); |
| 112 } else if (average_qp_upscale_.GetAverage(num_samples_upscale_, &avg_qp) && | 116 } else if (average_qp_upscale_.GetAverage(num_samples_upscale_, &avg_qp) && |
| 113 avg_qp <= low_qp_threshold_) { | 117 avg_qp <= low_qp_threshold_) { |
| 114 AdjustScale(true); | 118 AdjustScale(true); |
| 115 } | 119 } |
| 116 UpdateTargetResolution(frame.width(), frame.height()); | 120 UpdateTargetResolution(width, height); |
| 117 } | 121 } |
| 118 | 122 |
| 119 QualityScaler::Resolution QualityScaler::GetScaledResolution() const { | 123 QualityScaler::Resolution QualityScaler::GetScaledResolution() const { |
| 120 return res_; | 124 return res_; |
| 121 } | 125 } |
| 122 | 126 |
| 123 const VideoFrame& QualityScaler::GetScaledFrame(const VideoFrame& frame) { | 127 rtc::scoped_refptr<VideoFrameBuffer> QualityScaler::GetScaledFrame( |
| 128 const rtc::scoped_refptr<VideoFrameBuffer>& frame) { | |
| 124 Resolution res = GetScaledResolution(); | 129 Resolution res = GetScaledResolution(); |
| 125 if (res.width == frame.width()) | 130 int src_width = frame->width(); |
| 131 int src_height = frame->height(); | |
| 132 | |
| 133 if (res.width == src_width && res.height == src_height) | |
| 126 return frame; | 134 return frame; |
| 135 rtc::scoped_refptr<I420Buffer> scaled = | |
| 136 pool_.CreateBuffer(res.width, res.height); | |
| 127 | 137 |
| 128 scaler_.Set(frame.width(), frame.height(), res.width, res.height, kI420, | 138 I420Buffer::CenterCropAndScale(scaled, frame); |
| 129 kI420, kScaleBox); | |
| 130 if (scaler_.Scale(frame, &scaled_frame_) != 0) | |
| 131 return frame; | |
| 132 | 139 |
| 133 // TODO(perkj): Refactor the scaler to not own |scaled_frame|. VideoFrame are | 140 return scaled; |
| 134 // just thin wrappers so instead the scaler should return a | |
| 135 // rtc::scoped_refptr<VideoFrameBuffer> and a new VideoFrame be created with | |
| 136 // the meta data from |frame|. That way we would not have to set all these | |
| 137 // meta data. | |
| 138 scaled_frame_.set_ntp_time_ms(frame.ntp_time_ms()); | |
| 139 scaled_frame_.set_timestamp(frame.timestamp()); | |
| 140 scaled_frame_.set_render_time_ms(frame.render_time_ms()); | |
| 141 scaled_frame_.set_rotation(frame.rotation()); | |
| 142 | |
| 143 return scaled_frame_; | |
| 144 } | 141 } |
| 145 | 142 |
| 146 void QualityScaler::UpdateTargetResolution(int frame_width, int frame_height) { | 143 void QualityScaler::UpdateTargetResolution(int frame_width, int frame_height) { |
| 147 assert(downscale_shift_ >= 0); | 144 assert(downscale_shift_ >= 0); |
| 148 int shifts_performed = 0; | 145 int shifts_performed = 0; |
| 149 for (int shift = downscale_shift_; | 146 for (int shift = downscale_shift_; |
| 150 shift > 0 && (frame_width / 2 >= kMinDownscaleDimension) && | 147 shift > 0 && (frame_width / 2 >= kMinDownscaleDimension) && |
| 151 (frame_height / 2 >= kMinDownscaleDimension); | 148 (frame_height / 2 >= kMinDownscaleDimension); |
| 152 --shift, ++shifts_performed) { | 149 --shift, ++shifts_performed) { |
| 153 frame_width /= 2; | 150 frame_width /= 2; |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 183 if (downscale_shift_ < 0) | 180 if (downscale_shift_ < 0) |
| 184 downscale_shift_ = 0; | 181 downscale_shift_ = 0; |
| 185 if (!up) { | 182 if (!up) { |
| 186 // First downscale hit, start using a slower threshold for going up. | 183 // First downscale hit, start using a slower threshold for going up. |
| 187 measure_seconds_upscale_ = kMeasureSecondsUpscale; | 184 measure_seconds_upscale_ = kMeasureSecondsUpscale; |
| 188 UpdateSampleCounts(); | 185 UpdateSampleCounts(); |
| 189 } | 186 } |
| 190 } | 187 } |
| 191 | 188 |
| 192 } // namespace webrtc | 189 } // namespace webrtc |
| OLD | NEW |