blob: 764b5ed8e37e3238c60996c14327c1a4db62137e [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#ifndef WEBRTC_MODULES_VIDEO_CODING_QM_SELECT_H_
12#define WEBRTC_MODULES_VIDEO_CODING_QM_SELECT_H_
13
pbos@webrtc.orga4407322013-07-16 12:32:05 +000014#include "webrtc/common_types.h"
15#include "webrtc/typedefs.h"
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +000016
marpan@google.com86548c62011-07-12 17:12:57 +000017/******************************************************/
18/* Quality Modes: Resolution and Robustness settings */
19/******************************************************/
niklase@google.com470e71d2011-07-07 08:21:25 +000020
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +000021namespace webrtc {
niklase@google.com470e71d2011-07-07 08:21:25 +000022struct VideoContentMetrics;
23
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +000024struct VCMResolutionScale {
25 VCMResolutionScale()
marpan@webrtc.orge22d81c2012-03-20 18:21:53 +000026 : codec_width(640),
27 codec_height(480),
28 frame_rate(30.0f),
29 spatial_width_fact(1.0f),
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +000030 spatial_height_fact(1.0f),
31 temporal_fact(1.0f),
marpan@webrtc.orge22d81c2012-03-20 18:21:53 +000032 change_resolution_spatial(false),
philipel9d3ab612015-12-21 04:12:39 -080033 change_resolution_temporal(false) {}
marpan@webrtc.orge22d81c2012-03-20 18:21:53 +000034 uint16_t codec_width;
35 uint16_t codec_height;
36 float frame_rate;
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +000037 float spatial_width_fact;
38 float spatial_height_fact;
39 float temporal_fact;
marpan@webrtc.orge22d81c2012-03-20 18:21:53 +000040 bool change_resolution_spatial;
41 bool change_resolution_temporal;
niklase@google.com470e71d2011-07-07 08:21:25 +000042};
43
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +000044enum ImageType {
philipel9d3ab612015-12-21 04:12:39 -080045 kQCIF = 0, // 176x144
46 kHCIF, // 264x216 = half(~3/4x3/4) CIF.
47 kQVGA, // 320x240 = quarter VGA.
48 kCIF, // 352x288
49 kHVGA, // 480x360 = half(~3/4x3/4) VGA.
50 kVGA, // 640x480
51 kQFULLHD, // 960x540 = quarter FULLHD, and half(~3/4x3/4) WHD.
52 kWHD, // 1280x720
53 kFULLHD, // 1920x1080
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +000054 kNumImageTypes
55};
56
philipel9d3ab612015-12-21 04:12:39 -080057const uint32_t kSizeOfImageType[kNumImageTypes] = {
58 25344, 57024, 76800, 101376, 172800, 307200, 518400, 921600, 2073600};
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +000059
marpan@webrtc.orge22d81c2012-03-20 18:21:53 +000060enum FrameRateLevelClass {
61 kFrameRateLow,
62 kFrameRateMiddle1,
63 kFrameRateMiddle2,
64 kFrameRateHigh
65};
66
philipel9d3ab612015-12-21 04:12:39 -080067enum ContentLevelClass { kLow, kHigh, kDefault };
niklase@google.com470e71d2011-07-07 08:21:25 +000068
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +000069struct VCMContFeature {
philipel9d3ab612015-12-21 04:12:39 -080070 VCMContFeature() : value(0.0f), level(kDefault) {}
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +000071 void Reset() {
72 value = 0.0f;
73 level = kDefault;
74 }
75 float value;
marpan@webrtc.orge22d81c2012-03-20 18:21:53 +000076 ContentLevelClass level;
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +000077};
niklase@google.com470e71d2011-07-07 08:21:25 +000078
philipel9d3ab612015-12-21 04:12:39 -080079enum UpDownAction { kUpResolution, kDownResolution };
niklase@google.com470e71d2011-07-07 08:21:25 +000080
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +000081enum SpatialAction {
82 kNoChangeSpatial,
philipel9d3ab612015-12-21 04:12:39 -080083 kOneHalfSpatialUniform, // 3/4 x 3/4: 9/6 ~1/2 pixel reduction.
84 kOneQuarterSpatialUniform, // 1/2 x 1/2: 1/4 pixel reduction.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +000085 kNumModesSpatial
86};
87
88enum TemporalAction {
89 kNoChangeTemporal,
philipel9d3ab612015-12-21 04:12:39 -080090 kTwoThirdsTemporal, // 2/3 frame rate reduction
91 kOneHalfTemporal, // 1/2 frame rate reduction
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +000092 kNumModesTemporal
93};
94
95struct ResolutionAction {
philipel9d3ab612015-12-21 04:12:39 -080096 ResolutionAction() : spatial(kNoChangeSpatial), temporal(kNoChangeTemporal) {}
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +000097 SpatialAction spatial;
98 TemporalAction temporal;
99};
100
101// Down-sampling factors for spatial (width and height), and temporal.
philipel9d3ab612015-12-21 04:12:39 -0800102const float kFactorWidthSpatial[kNumModesSpatial] = {1.0f, 4.0f / 3.0f, 2.0f};
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000103
philipel9d3ab612015-12-21 04:12:39 -0800104const float kFactorHeightSpatial[kNumModesSpatial] = {1.0f, 4.0f / 3.0f, 2.0f};
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000105
philipel9d3ab612015-12-21 04:12:39 -0800106const float kFactorTemporal[kNumModesTemporal] = {1.0f, 1.5f, 2.0f};
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000107
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000108enum EncoderState {
109 kStableEncoding, // Low rate mis-match, stable buffer levels.
110 kStressedEncoding, // Significant over-shooting of target rate,
111 // Buffer under-flow, etc.
112 kEasyEncoding // Significant under-shooting of target rate.
niklase@google.com470e71d2011-07-07 08:21:25 +0000113};
114
marpan@google.com86548c62011-07-12 17:12:57 +0000115// QmMethod class: main class for resolution and robustness settings
116
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000117class VCMQmMethod {
118 public:
119 VCMQmMethod();
120 virtual ~VCMQmMethod();
niklase@google.com470e71d2011-07-07 08:21:25 +0000121
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000122 // Reset values
123 void ResetQM();
124 virtual void Reset() = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000125
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000126 // Compute content class.
127 uint8_t ComputeContentClass();
niklase@google.com470e71d2011-07-07 08:21:25 +0000128
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000129 // Update with the content metrics.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000130 void UpdateContent(const VideoContentMetrics* content_metrics);
niklase@google.com470e71d2011-07-07 08:21:25 +0000131
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000132 // Compute spatial texture magnitude and level.
133 // Spatial texture is a spatial prediction error measure.
134 void ComputeSpatial();
marpan@webrtc.orgbd5648f2012-02-17 23:16:58 +0000135
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000136 // Compute motion magnitude and level for NFD metric.
137 // NFD is normalized frame difference (normalized by spatial variance).
138 void ComputeMotionNFD();
niklase@google.com470e71d2011-07-07 08:21:25 +0000139
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000140 // Get the imageType (CIF, VGA, HD, etc) for the system width/height.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000141 ImageType GetImageType(uint16_t width, uint16_t height);
142
143 // Return the closest image type.
144 ImageType FindClosestImageType(uint16_t width, uint16_t height);
marpan@webrtc.orgbd5648f2012-02-17 23:16:58 +0000145
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000146 // Get the frame rate level.
marpan@webrtc.orge22d81c2012-03-20 18:21:53 +0000147 FrameRateLevelClass FrameRateLevel(float frame_rate);
niklase@google.com470e71d2011-07-07 08:21:25 +0000148
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000149 protected:
150 // Content Data.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000151 const VideoContentMetrics* content_metrics_;
niklase@google.com470e71d2011-07-07 08:21:25 +0000152
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000153 // Encoder frame sizes and native frame sizes.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000154 uint16_t width_;
155 uint16_t height_;
marpan@webrtc.orge22d81c2012-03-20 18:21:53 +0000156 float user_frame_rate_;
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000157 uint16_t native_width_;
158 uint16_t native_height_;
marpan@webrtc.orge22d81c2012-03-20 18:21:53 +0000159 float native_frame_rate_;
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000160 float aspect_ratio_;
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000161 // Image type and frame rate leve, for the current encoder resolution.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000162 ImageType image_type_;
marpan@webrtc.orge22d81c2012-03-20 18:21:53 +0000163 FrameRateLevelClass framerate_level_;
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000164 // Content class data.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000165 VCMContFeature motion_;
166 VCMContFeature spatial_;
167 uint8_t content_class_;
168 bool init_;
marpan@google.com86548c62011-07-12 17:12:57 +0000169};
170
171// Resolution settings class
172
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000173class VCMQmResolution : public VCMQmMethod {
174 public:
175 VCMQmResolution();
176 virtual ~VCMQmResolution();
marpan@google.com86548c62011-07-12 17:12:57 +0000177
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000178 // Reset all quantities.
179 virtual void Reset();
marpan@google.com86548c62011-07-12 17:12:57 +0000180
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000181 // Reset rate quantities and counters after every SelectResolution() call.
182 void ResetRates();
marpan@google.com86548c62011-07-12 17:12:57 +0000183
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000184 // Reset down-sampling state.
185 void ResetDownSamplingState();
marpan@google.com86548c62011-07-12 17:12:57 +0000186
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000187 // Get the encoder state.
188 EncoderState GetEncoderState();
marpan@google.com86548c62011-07-12 17:12:57 +0000189
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000190 // Initialize after SetEncodingData in media_opt.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000191 int Initialize(float bitrate,
192 float user_framerate,
193 uint16_t width,
194 uint16_t height,
195 int num_layers);
marpan@google.com86548c62011-07-12 17:12:57 +0000196
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000197 // Update the encoder frame size.
marpan@webrtc.orge22d81c2012-03-20 18:21:53 +0000198 void UpdateCodecParameters(float frame_rate, uint16_t width, uint16_t height);
marpan@google.com86548c62011-07-12 17:12:57 +0000199
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000200 // Update with actual bit rate (size of the latest encoded frame)
201 // and frame type, after every encoded frame.
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000202 void UpdateEncodedSize(size_t encoded_size);
marpan@google.com86548c62011-07-12 17:12:57 +0000203
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000204 // Update with new target bitrate, actual encoder sent rate, frame_rate,
205 // loss rate: every ~1 sec from SetTargetRates in media_opt.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000206 void UpdateRates(float target_bitrate,
207 float encoder_sent_rate,
208 float incoming_framerate,
209 uint8_t packet_loss);
marpan@google.com86548c62011-07-12 17:12:57 +0000210
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000211 // Extract ST (spatio-temporal) resolution action.
212 // Inputs: qm: Reference to the quality modes pointer.
213 // Output: the spatial and/or temporal scale change.
214 int SelectResolution(VCMResolutionScale** qm);
niklase@google.com470e71d2011-07-07 08:21:25 +0000215
marpan@webrtc.orge22d81c2012-03-20 18:21:53 +0000216 private:
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000217 // Set the default resolution action.
218 void SetDefaultAction();
219
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000220 // Compute rates for the selection of down-sampling action.
221 void ComputeRatesForSelection();
niklase@google.com470e71d2011-07-07 08:21:25 +0000222
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000223 // Compute the encoder state.
224 void ComputeEncoderState();
niklase@google.com470e71d2011-07-07 08:21:25 +0000225
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000226 // Return true if the action is to go back up in resolution.
227 bool GoingUpResolution();
228
229 // Return true if the action is to go down in resolution.
230 bool GoingDownResolution();
231
232 // Check the condition for going up in resolution by the scale factors:
233 // |facWidth|, |facHeight|, |facTemp|.
234 // |scaleFac| is a scale factor for the transition rate.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000235 bool ConditionForGoingUp(float fac_width,
236 float fac_height,
237 float fac_temp,
238 float scale_fac);
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000239
240 // Get the bitrate threshold for the resolution action.
241 // The case |facWidth|=|facHeight|=|facTemp|==1 is for down-sampling action.
242 // |scaleFac| is a scale factor for the transition rate.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000243 float GetTransitionRate(float fac_width,
244 float fac_height,
245 float fac_temp,
246 float scale_fac);
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000247
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000248 // Update the down-sampling state.
249 void UpdateDownsamplingState(UpDownAction up_down);
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000250
marpan@webrtc.orge22d81c2012-03-20 18:21:53 +0000251 // Update the codec frame size and frame rate.
252 void UpdateCodecResolution();
253
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000254 // Return a state based on average target rate relative transition rate.
255 uint8_t RateClass(float transition_rate);
256
257 // Adjust the action selected from the table.
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000258 void AdjustAction();
259
marpan@webrtc.orge22d81c2012-03-20 18:21:53 +0000260 // Covert 2 stages of 3/4 (=9/16) spatial decimation to 1/2.
261 void ConvertSpatialFractionalToWhole();
262
marpan@webrtc.orgc5b392e2012-06-29 21:44:55 +0000263 // Returns true if the new frame sizes, under the selected spatial action,
264 // are of even size.
265 bool EvenFrameSize();
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000266
267 // Insert latest down-sampling action into the history list.
268 void InsertLatestDownAction();
269
270 // Remove the last (first element) down-sampling action from the list.
271 void RemoveLastDownAction();
272
273 // Check constraints on the amount of down-sampling allowed.
274 void ConstrainAmountOfDownSampling();
275
276 // For going up in resolution: pick spatial or temporal action,
277 // if both actions were separately selected.
278 void PickSpatialOrTemporal();
279
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000280 // Select the directional (1x2 or 2x1) spatial down-sampling action.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000281 void SelectSpatialDirectionMode(float transition_rate);
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000282
philipel9d3ab612015-12-21 04:12:39 -0800283 enum { kDownActionHistorySize = 10 };
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000284
285 VCMResolutionScale* qm_;
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000286 // Encoder rate control parameters.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000287 float target_bitrate_;
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000288 float incoming_framerate_;
289 float per_frame_bandwidth_;
290 float buffer_level_;
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000291
292 // Data accumulated every ~1sec from MediaOpt.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000293 float sum_target_rate_;
294 float sum_incoming_framerate_;
295 float sum_rate_MM_;
296 float sum_rate_MM_sgn_;
297 float sum_packet_loss_;
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000298 // Counters.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000299 uint32_t frame_cnt_;
300 uint32_t frame_cnt_delta_;
301 uint32_t update_rate_cnt_;
302 uint32_t low_buffer_cnt_;
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000303
304 // Resolution state parameters.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000305 float state_dec_factor_spatial_;
306 float state_dec_factor_temporal_;
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000307
308 // Quantities used for selection.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000309 float avg_target_rate_;
310 float avg_incoming_framerate_;
311 float avg_ratio_buffer_low_;
312 float avg_rate_mismatch_;
313 float avg_rate_mismatch_sgn_;
314 float avg_packet_loss_;
315 EncoderState encoder_state_;
316 ResolutionAction action_;
317 // Short history of the down-sampling actions from the Initialize() state.
318 // This is needed for going up in resolution. Since the total amount of
319 // down-sampling actions are constrained, the length of the list need not be
320 // large: i.e., (4/3) ^{kDownActionHistorySize} <= kMaxDownSample.
321 ResolutionAction down_action_history_[kDownActionHistorySize];
322 int num_layers_;
marpan@google.com86548c62011-07-12 17:12:57 +0000323};
niklase@google.com470e71d2011-07-07 08:21:25 +0000324
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000325// Robustness settings class.
niklase@google.com470e71d2011-07-07 08:21:25 +0000326
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000327class VCMQmRobustness : public VCMQmMethod {
328 public:
329 VCMQmRobustness();
330 ~VCMQmRobustness();
niklase@google.com470e71d2011-07-07 08:21:25 +0000331
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000332 virtual void Reset();
niklase@google.com470e71d2011-07-07 08:21:25 +0000333
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000334 // Adjust FEC rate based on content: every ~1 sec from SetTargetRates.
335 // Returns an adjustment factor.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000336 float AdjustFecFactor(uint8_t code_rate_delta,
337 float total_rate,
338 float framerate,
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000339 int64_t rtt_time,
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000340 uint8_t packet_loss);
marpan@google.com86548c62011-07-12 17:12:57 +0000341
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000342 // Set the UEP protection on/off.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000343 bool SetUepProtection(uint8_t code_rate_delta,
344 float total_rate,
345 uint8_t packet_loss,
346 bool frame_type);
marpan@google.com86548c62011-07-12 17:12:57 +0000347
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000348 private:
349 // Previous state of network parameters.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000350 float prev_total_rate_;
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000351 int64_t prev_rtt_time_;
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000352 uint8_t prev_packet_loss_;
353 uint8_t prev_code_rate_delta_;
niklase@google.com470e71d2011-07-07 08:21:25 +0000354};
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000355} // namespace webrtc
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000356#endif // WEBRTC_MODULES_VIDEO_CODING_QM_SELECT_H_