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 |