blob: 079e7f88792eba5b508dcf61195d2e807a65cd05 [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),
33 change_resolution_temporal(false) {
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +000034 }
marpan@webrtc.orge22d81c2012-03-20 18:21:53 +000035 uint16_t codec_width;
36 uint16_t codec_height;
37 float frame_rate;
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +000038 float spatial_width_fact;
39 float spatial_height_fact;
40 float temporal_fact;
marpan@webrtc.orge22d81c2012-03-20 18:21:53 +000041 bool change_resolution_spatial;
42 bool change_resolution_temporal;
niklase@google.com470e71d2011-07-07 08:21:25 +000043};
44
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +000045enum ImageType {
46 kQCIF = 0, // 176x144
47 kHCIF, // 264x216 = half(~3/4x3/4) CIF.
48 kQVGA, // 320x240 = quarter VGA.
49 kCIF, // 352x288
50 kHVGA, // 480x360 = half(~3/4x3/4) VGA.
51 kVGA, // 640x480
52 kQFULLHD, // 960x540 = quarter FULLHD, and half(~3/4x3/4) WHD.
53 kWHD, // 1280x720
54 kFULLHD, // 1920x1080
55 kNumImageTypes
56};
57
58const uint32_t kSizeOfImageType[kNumImageTypes] =
59{ 25344, 57024, 76800, 101376, 172800, 307200, 518400, 921600, 2073600 };
60
marpan@webrtc.orge22d81c2012-03-20 18:21:53 +000061enum FrameRateLevelClass {
62 kFrameRateLow,
63 kFrameRateMiddle1,
64 kFrameRateMiddle2,
65 kFrameRateHigh
66};
67
68enum ContentLevelClass {
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +000069 kLow,
70 kHigh,
71 kDefault
niklase@google.com470e71d2011-07-07 08:21:25 +000072};
73
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +000074struct VCMContFeature {
75 VCMContFeature()
76 : value(0.0f),
77 level(kDefault) {
78 }
79 void Reset() {
80 value = 0.0f;
81 level = kDefault;
82 }
83 float value;
marpan@webrtc.orge22d81c2012-03-20 18:21:53 +000084 ContentLevelClass level;
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +000085};
niklase@google.com470e71d2011-07-07 08:21:25 +000086
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +000087enum UpDownAction {
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +000088 kUpResolution,
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +000089 kDownResolution
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +000090};
niklase@google.com470e71d2011-07-07 08:21:25 +000091
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +000092enum SpatialAction {
93 kNoChangeSpatial,
94 kOneHalfSpatialUniform, // 3/4 x 3/4: 9/6 ~1/2 pixel reduction.
95 kOneQuarterSpatialUniform, // 1/2 x 1/2: 1/4 pixel reduction.
96 kNumModesSpatial
97};
98
99enum TemporalAction {
100 kNoChangeTemporal,
101 kTwoThirdsTemporal, // 2/3 frame rate reduction
102 kOneHalfTemporal, // 1/2 frame rate reduction
103 kNumModesTemporal
104};
105
106struct ResolutionAction {
107 ResolutionAction()
108 : spatial(kNoChangeSpatial),
109 temporal(kNoChangeTemporal) {
110 }
111 SpatialAction spatial;
112 TemporalAction temporal;
113};
114
115// Down-sampling factors for spatial (width and height), and temporal.
116const float kFactorWidthSpatial[kNumModesSpatial] =
117 { 1.0f, 4.0f / 3.0f, 2.0f };
118
119const float kFactorHeightSpatial[kNumModesSpatial] =
120 { 1.0f, 4.0f / 3.0f, 2.0f };
121
122const float kFactorTemporal[kNumModesTemporal] =
123 { 1.0f, 1.5f, 2.0f };
124
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000125enum EncoderState {
126 kStableEncoding, // Low rate mis-match, stable buffer levels.
127 kStressedEncoding, // Significant over-shooting of target rate,
128 // Buffer under-flow, etc.
129 kEasyEncoding // Significant under-shooting of target rate.
niklase@google.com470e71d2011-07-07 08:21:25 +0000130};
131
marpan@google.com86548c62011-07-12 17:12:57 +0000132// QmMethod class: main class for resolution and robustness settings
133
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000134class VCMQmMethod {
135 public:
136 VCMQmMethod();
137 virtual ~VCMQmMethod();
niklase@google.com470e71d2011-07-07 08:21:25 +0000138
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000139 // Reset values
140 void ResetQM();
141 virtual void Reset() = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000142
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000143 // Compute content class.
144 uint8_t ComputeContentClass();
niklase@google.com470e71d2011-07-07 08:21:25 +0000145
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000146 // Update with the content metrics.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000147 void UpdateContent(const VideoContentMetrics* content_metrics);
niklase@google.com470e71d2011-07-07 08:21:25 +0000148
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000149 // Compute spatial texture magnitude and level.
150 // Spatial texture is a spatial prediction error measure.
151 void ComputeSpatial();
marpan@webrtc.orgbd5648f2012-02-17 23:16:58 +0000152
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000153 // Compute motion magnitude and level for NFD metric.
154 // NFD is normalized frame difference (normalized by spatial variance).
155 void ComputeMotionNFD();
niklase@google.com470e71d2011-07-07 08:21:25 +0000156
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000157 // Get the imageType (CIF, VGA, HD, etc) for the system width/height.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000158 ImageType GetImageType(uint16_t width, uint16_t height);
159
160 // Return the closest image type.
161 ImageType FindClosestImageType(uint16_t width, uint16_t height);
marpan@webrtc.orgbd5648f2012-02-17 23:16:58 +0000162
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000163 // Get the frame rate level.
marpan@webrtc.orge22d81c2012-03-20 18:21:53 +0000164 FrameRateLevelClass FrameRateLevel(float frame_rate);
niklase@google.com470e71d2011-07-07 08:21:25 +0000165
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000166 protected:
167 // Content Data.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000168 const VideoContentMetrics* content_metrics_;
niklase@google.com470e71d2011-07-07 08:21:25 +0000169
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000170 // Encoder frame sizes and native frame sizes.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000171 uint16_t width_;
172 uint16_t height_;
marpan@webrtc.orge22d81c2012-03-20 18:21:53 +0000173 float user_frame_rate_;
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000174 uint16_t native_width_;
175 uint16_t native_height_;
marpan@webrtc.orge22d81c2012-03-20 18:21:53 +0000176 float native_frame_rate_;
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000177 float aspect_ratio_;
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000178 // Image type and frame rate leve, for the current encoder resolution.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000179 ImageType image_type_;
marpan@webrtc.orge22d81c2012-03-20 18:21:53 +0000180 FrameRateLevelClass framerate_level_;
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000181 // Content class data.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000182 VCMContFeature motion_;
183 VCMContFeature spatial_;
184 uint8_t content_class_;
185 bool init_;
marpan@google.com86548c62011-07-12 17:12:57 +0000186};
187
188// Resolution settings class
189
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000190class VCMQmResolution : public VCMQmMethod {
191 public:
192 VCMQmResolution();
193 virtual ~VCMQmResolution();
marpan@google.com86548c62011-07-12 17:12:57 +0000194
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000195 // Reset all quantities.
196 virtual void Reset();
marpan@google.com86548c62011-07-12 17:12:57 +0000197
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000198 // Reset rate quantities and counters after every SelectResolution() call.
199 void ResetRates();
marpan@google.com86548c62011-07-12 17:12:57 +0000200
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000201 // Reset down-sampling state.
202 void ResetDownSamplingState();
marpan@google.com86548c62011-07-12 17:12:57 +0000203
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000204 // Get the encoder state.
205 EncoderState GetEncoderState();
marpan@google.com86548c62011-07-12 17:12:57 +0000206
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000207 // Initialize after SetEncodingData in media_opt.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000208 int Initialize(float bitrate,
209 float user_framerate,
210 uint16_t width,
211 uint16_t height,
212 int num_layers);
marpan@google.com86548c62011-07-12 17:12:57 +0000213
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000214 // Update the encoder frame size.
marpan@webrtc.orge22d81c2012-03-20 18:21:53 +0000215 void UpdateCodecParameters(float frame_rate, uint16_t width, uint16_t height);
marpan@google.com86548c62011-07-12 17:12:57 +0000216
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000217 // Update with actual bit rate (size of the latest encoded frame)
218 // and frame type, after every encoded frame.
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000219 void UpdateEncodedSize(size_t encoded_size);
marpan@google.com86548c62011-07-12 17:12:57 +0000220
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000221 // Update with new target bitrate, actual encoder sent rate, frame_rate,
222 // loss rate: every ~1 sec from SetTargetRates in media_opt.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000223 void UpdateRates(float target_bitrate,
224 float encoder_sent_rate,
225 float incoming_framerate,
226 uint8_t packet_loss);
marpan@google.com86548c62011-07-12 17:12:57 +0000227
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000228 // Extract ST (spatio-temporal) resolution action.
229 // Inputs: qm: Reference to the quality modes pointer.
230 // Output: the spatial and/or temporal scale change.
231 int SelectResolution(VCMResolutionScale** qm);
niklase@google.com470e71d2011-07-07 08:21:25 +0000232
marpan@webrtc.orge22d81c2012-03-20 18:21:53 +0000233 private:
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000234 // Set the default resolution action.
235 void SetDefaultAction();
236
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000237 // Compute rates for the selection of down-sampling action.
238 void ComputeRatesForSelection();
niklase@google.com470e71d2011-07-07 08:21:25 +0000239
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000240 // Compute the encoder state.
241 void ComputeEncoderState();
niklase@google.com470e71d2011-07-07 08:21:25 +0000242
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000243 // Return true if the action is to go back up in resolution.
244 bool GoingUpResolution();
245
246 // Return true if the action is to go down in resolution.
247 bool GoingDownResolution();
248
249 // Check the condition for going up in resolution by the scale factors:
250 // |facWidth|, |facHeight|, |facTemp|.
251 // |scaleFac| is a scale factor for the transition rate.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000252 bool ConditionForGoingUp(float fac_width,
253 float fac_height,
254 float fac_temp,
255 float scale_fac);
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000256
257 // Get the bitrate threshold for the resolution action.
258 // The case |facWidth|=|facHeight|=|facTemp|==1 is for down-sampling action.
259 // |scaleFac| is a scale factor for the transition rate.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000260 float GetTransitionRate(float fac_width,
261 float fac_height,
262 float fac_temp,
263 float scale_fac);
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000264
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000265 // Update the down-sampling state.
266 void UpdateDownsamplingState(UpDownAction up_down);
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000267
marpan@webrtc.orge22d81c2012-03-20 18:21:53 +0000268 // Update the codec frame size and frame rate.
269 void UpdateCodecResolution();
270
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000271 // Return a state based on average target rate relative transition rate.
272 uint8_t RateClass(float transition_rate);
273
274 // Adjust the action selected from the table.
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000275 void AdjustAction();
276
marpan@webrtc.orge22d81c2012-03-20 18:21:53 +0000277 // Covert 2 stages of 3/4 (=9/16) spatial decimation to 1/2.
278 void ConvertSpatialFractionalToWhole();
279
marpan@webrtc.orgc5b392e2012-06-29 21:44:55 +0000280 // Returns true if the new frame sizes, under the selected spatial action,
281 // are of even size.
282 bool EvenFrameSize();
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000283
284 // Insert latest down-sampling action into the history list.
285 void InsertLatestDownAction();
286
287 // Remove the last (first element) down-sampling action from the list.
288 void RemoveLastDownAction();
289
290 // Check constraints on the amount of down-sampling allowed.
291 void ConstrainAmountOfDownSampling();
292
293 // For going up in resolution: pick spatial or temporal action,
294 // if both actions were separately selected.
295 void PickSpatialOrTemporal();
296
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000297 // Select the directional (1x2 or 2x1) spatial down-sampling action.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000298 void SelectSpatialDirectionMode(float transition_rate);
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000299
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000300 enum { kDownActionHistorySize = 10};
301
302 VCMResolutionScale* qm_;
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000303 // Encoder rate control parameters.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000304 float target_bitrate_;
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000305 float incoming_framerate_;
306 float per_frame_bandwidth_;
307 float buffer_level_;
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000308
309 // Data accumulated every ~1sec from MediaOpt.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000310 float sum_target_rate_;
311 float sum_incoming_framerate_;
312 float sum_rate_MM_;
313 float sum_rate_MM_sgn_;
314 float sum_packet_loss_;
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000315 // Counters.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000316 uint32_t frame_cnt_;
317 uint32_t frame_cnt_delta_;
318 uint32_t update_rate_cnt_;
319 uint32_t low_buffer_cnt_;
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000320
321 // Resolution state parameters.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000322 float state_dec_factor_spatial_;
323 float state_dec_factor_temporal_;
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000324
325 // Quantities used for selection.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000326 float avg_target_rate_;
327 float avg_incoming_framerate_;
328 float avg_ratio_buffer_low_;
329 float avg_rate_mismatch_;
330 float avg_rate_mismatch_sgn_;
331 float avg_packet_loss_;
332 EncoderState encoder_state_;
333 ResolutionAction action_;
334 // Short history of the down-sampling actions from the Initialize() state.
335 // This is needed for going up in resolution. Since the total amount of
336 // down-sampling actions are constrained, the length of the list need not be
337 // large: i.e., (4/3) ^{kDownActionHistorySize} <= kMaxDownSample.
338 ResolutionAction down_action_history_[kDownActionHistorySize];
339 int num_layers_;
marpan@google.com86548c62011-07-12 17:12:57 +0000340};
niklase@google.com470e71d2011-07-07 08:21:25 +0000341
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000342// Robustness settings class.
niklase@google.com470e71d2011-07-07 08:21:25 +0000343
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000344class VCMQmRobustness : public VCMQmMethod {
345 public:
346 VCMQmRobustness();
347 ~VCMQmRobustness();
niklase@google.com470e71d2011-07-07 08:21:25 +0000348
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000349 virtual void Reset();
niklase@google.com470e71d2011-07-07 08:21:25 +0000350
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000351 // Adjust FEC rate based on content: every ~1 sec from SetTargetRates.
352 // Returns an adjustment factor.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000353 float AdjustFecFactor(uint8_t code_rate_delta,
354 float total_rate,
355 float framerate,
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000356 int64_t rtt_time,
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000357 uint8_t packet_loss);
marpan@google.com86548c62011-07-12 17:12:57 +0000358
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000359 // Set the UEP protection on/off.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000360 bool SetUepProtection(uint8_t code_rate_delta,
361 float total_rate,
362 uint8_t packet_loss,
363 bool frame_type);
marpan@google.com86548c62011-07-12 17:12:57 +0000364
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000365 private:
366 // Previous state of network parameters.
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000367 float prev_total_rate_;
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000368 int64_t prev_rtt_time_;
marpan@webrtc.orgaccf6072012-03-07 17:16:10 +0000369 uint8_t prev_packet_loss_;
370 uint8_t prev_code_rate_delta_;
niklase@google.com470e71d2011-07-07 08:21:25 +0000371};
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000372} // namespace webrtc
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +0000373#endif // WEBRTC_MODULES_VIDEO_CODING_QM_SELECT_H_