| 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  | 
|   10 #include "webrtc/modules/video_coding/utility/quality_scaler.h" |   11 #include "webrtc/modules/video_coding/utility/quality_scaler.h" | 
|   11  |   12  | 
|   12 namespace webrtc { |   13 namespace webrtc { | 
|   13  |   14  | 
|   14 namespace { |   15 namespace { | 
|   15 static const int kMinFps = 5; |   16 static const int kMinFps = 5; | 
|   16 // Threshold constant used until first downscale (to permit fast rampup). |   17 // Threshold constant used until first downscale (to permit fast rampup). | 
|   17 static const int kMeasureSecondsFastUpscale = 2; |   18 static const int kMeasureSecondsFastUpscale = 2; | 
|   18 static const int kMeasureSecondsUpscale = 5; |   19 static const int kMeasureSecondsUpscale = 5; | 
|   19 static const int kMeasureSecondsDownscale = 5; |   20 static const int kMeasureSecondsDownscale = 5; | 
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   87 void QualityScaler::ReportQP(int qp) { |   88 void QualityScaler::ReportQP(int qp) { | 
|   88   framedrop_percent_.AddSample(0); |   89   framedrop_percent_.AddSample(0); | 
|   89   average_qp_downscale_.AddSample(qp); |   90   average_qp_downscale_.AddSample(qp); | 
|   90   average_qp_upscale_.AddSample(qp); |   91   average_qp_upscale_.AddSample(qp); | 
|   91 } |   92 } | 
|   92  |   93  | 
|   93 void QualityScaler::ReportDroppedFrame() { |   94 void QualityScaler::ReportDroppedFrame() { | 
|   94   framedrop_percent_.AddSample(100); |   95   framedrop_percent_.AddSample(100); | 
|   95 } |   96 } | 
|   96  |   97  | 
|   97 void QualityScaler::OnEncodeFrame(const VideoFrame& frame) { |   98 void QualityScaler::OnEncodeFrame(int width, int height) { | 
|   98   // Should be set through InitEncode -> Should be set by now. |   99   // Should be set through InitEncode -> Should be set by now. | 
|   99   assert(low_qp_threshold_ >= 0); |  100   RTC_DCHECK_GE(low_qp_threshold_, 0); | 
|  100   assert(num_samples_upscale_ > 0); |  101   RTC_DCHECK_GT(num_samples_upscale_, 0u); | 
|  101   assert(num_samples_downscale_ > 0); |  102   RTC_DCHECK_GT(num_samples_downscale_, 0u); | 
|  102  |  103  | 
|  103   // Update scale factor. |  104   // Update scale factor. | 
|  104   int avg_drop = 0; |  105   int avg_drop = 0; | 
|  105   int avg_qp = 0; |  106   int avg_qp = 0; | 
|  106  |  107  | 
|  107   if ((framedrop_percent_.GetAverage(num_samples_downscale_, &avg_drop) && |  108   if ((framedrop_percent_.GetAverage(num_samples_downscale_, &avg_drop) && | 
|  108        avg_drop >= kFramedropPercentThreshold) || |  109        avg_drop >= kFramedropPercentThreshold) || | 
|  109       (average_qp_downscale_.GetAverage(num_samples_downscale_, &avg_qp) && |  110       (average_qp_downscale_.GetAverage(num_samples_downscale_, &avg_qp) && | 
|  110        avg_qp > high_qp_threshold_)) { |  111        avg_qp > high_qp_threshold_)) { | 
|  111     AdjustScale(false); |  112     AdjustScale(false); | 
|  112   } else if (average_qp_upscale_.GetAverage(num_samples_upscale_, &avg_qp) && |  113   } else if (average_qp_upscale_.GetAverage(num_samples_upscale_, &avg_qp) && | 
|  113              avg_qp <= low_qp_threshold_) { |  114              avg_qp <= low_qp_threshold_) { | 
|  114     AdjustScale(true); |  115     AdjustScale(true); | 
|  115   } |  116   } | 
|  116   UpdateTargetResolution(frame.width(), frame.height()); |  117   UpdateTargetResolution(width, height); | 
|  117 } |  118 } | 
|  118  |  119  | 
|  119 QualityScaler::Resolution QualityScaler::GetScaledResolution() const { |  120 QualityScaler::Resolution QualityScaler::GetScaledResolution() const { | 
|  120   return res_; |  121   return res_; | 
|  121 } |  122 } | 
|  122  |  123  | 
|  123 const VideoFrame& QualityScaler::GetScaledFrame(const VideoFrame& frame) { |  124 rtc::scoped_refptr<VideoFrameBuffer> QualityScaler::GetScaledBuffer( | 
 |  125     const rtc::scoped_refptr<VideoFrameBuffer>& frame) { | 
|  124   Resolution res = GetScaledResolution(); |  126   Resolution res = GetScaledResolution(); | 
|  125   if (res.width == frame.width()) |  127   int src_width = frame->width(); | 
 |  128   int src_height = frame->height(); | 
 |  129  | 
 |  130   if (res.width == src_width && res.height == src_height) | 
|  126     return frame; |  131     return frame; | 
 |  132   rtc::scoped_refptr<I420Buffer> scaled_buffer = | 
 |  133       pool_.CreateBuffer(res.width, res.height); | 
|  127  |  134  | 
|  128   scaler_.Set(frame.width(), frame.height(), res.width, res.height, kI420, |  135   scaled_buffer->ScaleFrom(frame); | 
|  129               kI420, kScaleBox); |  | 
|  130   if (scaler_.Scale(frame, &scaled_frame_) != 0) |  | 
|  131     return frame; |  | 
|  132  |  136  | 
|  133   // TODO(perkj): Refactor the scaler to not own |scaled_frame|. VideoFrame are |  137   return scaled_buffer; | 
|  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 } |  138 } | 
|  145  |  139  | 
|  146 void QualityScaler::UpdateTargetResolution(int frame_width, int frame_height) { |  140 void QualityScaler::UpdateTargetResolution(int frame_width, int frame_height) { | 
|  147   assert(downscale_shift_ >= 0); |  141   RTC_DCHECK_GE(downscale_shift_, 0); | 
|  148   int shifts_performed = 0; |  142   int shifts_performed = 0; | 
|  149   for (int shift = downscale_shift_; |  143   for (int shift = downscale_shift_; | 
|  150        shift > 0 && (frame_width / 2 >= kMinDownscaleDimension) && |  144        shift > 0 && (frame_width / 2 >= kMinDownscaleDimension) && | 
|  151        (frame_height / 2 >= kMinDownscaleDimension); |  145        (frame_height / 2 >= kMinDownscaleDimension); | 
|  152        --shift, ++shifts_performed) { |  146        --shift, ++shifts_performed) { | 
|  153     frame_width /= 2; |  147     frame_width /= 2; | 
|  154     frame_height /= 2; |  148     frame_height /= 2; | 
|  155   } |  149   } | 
|  156   // Clamp to number of shifts actually performed to not be stuck trying to |  150   // Clamp to number of shifts actually performed to not be stuck trying to | 
|  157   // scale way beyond QVGA. |  151   // scale way beyond QVGA. | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
|  183   if (downscale_shift_ < 0) |  177   if (downscale_shift_ < 0) | 
|  184     downscale_shift_ = 0; |  178     downscale_shift_ = 0; | 
|  185   if (!up) { |  179   if (!up) { | 
|  186     // First downscale hit, start using a slower threshold for going up. |  180     // First downscale hit, start using a slower threshold for going up. | 
|  187     measure_seconds_upscale_ = kMeasureSecondsUpscale; |  181     measure_seconds_upscale_ = kMeasureSecondsUpscale; | 
|  188     UpdateSampleCounts(); |  182     UpdateSampleCounts(); | 
|  189   } |  183   } | 
|  190 } |  184 } | 
|  191  |  185  | 
|  192 }  // namespace webrtc |  186 }  // namespace webrtc | 
| OLD | NEW |