/*
|
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
*
|
* Use of this source code is governed by a BSD-style license
|
* that can be found in the LICENSE file in the root of the source
|
* tree. An additional intellectual property rights grant can be found
|
* in the file PATENTS. All contributing project authors may
|
* be found in the AUTHORS file in the root of the source tree.
|
*/
|
|
#ifndef WEBRTC_MODULES_VIDEO_CODING_QM_SELECT_H_
|
#define WEBRTC_MODULES_VIDEO_CODING_QM_SELECT_H_
|
|
#include "webrtc/common_types.h"
|
#include "webrtc/typedefs.h"
|
|
/******************************************************/
|
/* Quality Modes: Resolution and Robustness settings */
|
/******************************************************/
|
|
namespace webrtc {
|
struct VideoContentMetrics;
|
|
struct VCMResolutionScale {
|
VCMResolutionScale()
|
: codec_width(640),
|
codec_height(480),
|
frame_rate(30.0f),
|
spatial_width_fact(1.0f),
|
spatial_height_fact(1.0f),
|
temporal_fact(1.0f),
|
change_resolution_spatial(false),
|
change_resolution_temporal(false) {}
|
uint16_t codec_width;
|
uint16_t codec_height;
|
float frame_rate;
|
float spatial_width_fact;
|
float spatial_height_fact;
|
float temporal_fact;
|
bool change_resolution_spatial;
|
bool change_resolution_temporal;
|
};
|
|
enum ImageType {
|
kQCIF = 0, // 176x144
|
kHCIF, // 264x216 = half(~3/4x3/4) CIF.
|
kQVGA, // 320x240 = quarter VGA.
|
kCIF, // 352x288
|
kHVGA, // 480x360 = half(~3/4x3/4) VGA.
|
kVGA, // 640x480
|
kQFULLHD, // 960x540 = quarter FULLHD, and half(~3/4x3/4) WHD.
|
kWHD, // 1280x720
|
kFULLHD, // 1920x1080
|
kNumImageTypes
|
};
|
|
const uint32_t kSizeOfImageType[kNumImageTypes] = {
|
25344, 57024, 76800, 101376, 172800, 307200, 518400, 921600, 2073600};
|
|
enum FrameRateLevelClass {
|
kFrameRateLow,
|
kFrameRateMiddle1,
|
kFrameRateMiddle2,
|
kFrameRateHigh
|
};
|
|
enum ContentLevelClass { kLow, kHigh, kDefault };
|
|
struct VCMContFeature {
|
VCMContFeature() : value(0.0f), level(kDefault) {}
|
void Reset() {
|
value = 0.0f;
|
level = kDefault;
|
}
|
float value;
|
ContentLevelClass level;
|
};
|
|
enum UpDownAction { kUpResolution, kDownResolution };
|
|
enum SpatialAction {
|
kNoChangeSpatial,
|
kOneHalfSpatialUniform, // 3/4 x 3/4: 9/6 ~1/2 pixel reduction.
|
kOneQuarterSpatialUniform, // 1/2 x 1/2: 1/4 pixel reduction.
|
kNumModesSpatial
|
};
|
|
enum TemporalAction {
|
kNoChangeTemporal,
|
kTwoThirdsTemporal, // 2/3 frame rate reduction
|
kOneHalfTemporal, // 1/2 frame rate reduction
|
kNumModesTemporal
|
};
|
|
struct ResolutionAction {
|
ResolutionAction() : spatial(kNoChangeSpatial), temporal(kNoChangeTemporal) {}
|
SpatialAction spatial;
|
TemporalAction temporal;
|
};
|
|
// Down-sampling factors for spatial (width and height), and temporal.
|
const float kFactorWidthSpatial[kNumModesSpatial] = {1.0f, 4.0f / 3.0f, 2.0f};
|
|
const float kFactorHeightSpatial[kNumModesSpatial] = {1.0f, 4.0f / 3.0f, 2.0f};
|
|
const float kFactorTemporal[kNumModesTemporal] = {1.0f, 1.5f, 2.0f};
|
|
enum EncoderState {
|
kStableEncoding, // Low rate mis-match, stable buffer levels.
|
kStressedEncoding, // Significant over-shooting of target rate,
|
// Buffer under-flow, etc.
|
kEasyEncoding // Significant under-shooting of target rate.
|
};
|
|
// QmMethod class: main class for resolution and robustness settings
|
|
class VCMQmMethod {
|
public:
|
VCMQmMethod();
|
virtual ~VCMQmMethod();
|
|
// Reset values
|
void ResetQM();
|
virtual void Reset() = 0;
|
|
// Compute content class.
|
uint8_t ComputeContentClass();
|
|
// Update with the content metrics.
|
void UpdateContent(const VideoContentMetrics* content_metrics);
|
|
// Compute spatial texture magnitude and level.
|
// Spatial texture is a spatial prediction error measure.
|
void ComputeSpatial();
|
|
// Compute motion magnitude and level for NFD metric.
|
// NFD is normalized frame difference (normalized by spatial variance).
|
void ComputeMotionNFD();
|
|
// Get the imageType (CIF, VGA, HD, etc) for the system width/height.
|
ImageType GetImageType(uint16_t width, uint16_t height);
|
|
// Return the closest image type.
|
ImageType FindClosestImageType(uint16_t width, uint16_t height);
|
|
// Get the frame rate level.
|
FrameRateLevelClass FrameRateLevel(float frame_rate);
|
|
protected:
|
// Content Data.
|
const VideoContentMetrics* content_metrics_;
|
|
// Encoder frame sizes and native frame sizes.
|
uint16_t width_;
|
uint16_t height_;
|
float user_frame_rate_;
|
uint16_t native_width_;
|
uint16_t native_height_;
|
float native_frame_rate_;
|
float aspect_ratio_;
|
// Image type and frame rate leve, for the current encoder resolution.
|
ImageType image_type_;
|
FrameRateLevelClass framerate_level_;
|
// Content class data.
|
VCMContFeature motion_;
|
VCMContFeature spatial_;
|
uint8_t content_class_;
|
bool init_;
|
};
|
|
// Resolution settings class
|
|
class VCMQmResolution : public VCMQmMethod {
|
public:
|
VCMQmResolution();
|
virtual ~VCMQmResolution();
|
|
// Reset all quantities.
|
virtual void Reset();
|
|
// Reset rate quantities and counters after every SelectResolution() call.
|
void ResetRates();
|
|
// Reset down-sampling state.
|
void ResetDownSamplingState();
|
|
// Get the encoder state.
|
EncoderState GetEncoderState();
|
|
// Initialize after SetEncodingData in media_opt.
|
int Initialize(float bitrate,
|
float user_framerate,
|
uint16_t width,
|
uint16_t height,
|
int num_layers);
|
|
// Update the encoder frame size.
|
void UpdateCodecParameters(float frame_rate, uint16_t width, uint16_t height);
|
|
// Update with actual bit rate (size of the latest encoded frame)
|
// and frame type, after every encoded frame.
|
void UpdateEncodedSize(size_t encoded_size);
|
|
// Update with new target bitrate, actual encoder sent rate, frame_rate,
|
// loss rate: every ~1 sec from SetTargetRates in media_opt.
|
void UpdateRates(float target_bitrate,
|
float encoder_sent_rate,
|
float incoming_framerate,
|
uint8_t packet_loss);
|
|
// Extract ST (spatio-temporal) resolution action.
|
// Inputs: qm: Reference to the quality modes pointer.
|
// Output: the spatial and/or temporal scale change.
|
int SelectResolution(VCMResolutionScale** qm);
|
|
private:
|
// Set the default resolution action.
|
void SetDefaultAction();
|
|
// Compute rates for the selection of down-sampling action.
|
void ComputeRatesForSelection();
|
|
// Compute the encoder state.
|
void ComputeEncoderState();
|
|
// Return true if the action is to go back up in resolution.
|
bool GoingUpResolution();
|
|
// Return true if the action is to go down in resolution.
|
bool GoingDownResolution();
|
|
// Check the condition for going up in resolution by the scale factors:
|
// |facWidth|, |facHeight|, |facTemp|.
|
// |scaleFac| is a scale factor for the transition rate.
|
bool ConditionForGoingUp(float fac_width,
|
float fac_height,
|
float fac_temp,
|
float scale_fac);
|
|
// Get the bitrate threshold for the resolution action.
|
// The case |facWidth|=|facHeight|=|facTemp|==1 is for down-sampling action.
|
// |scaleFac| is a scale factor for the transition rate.
|
float GetTransitionRate(float fac_width,
|
float fac_height,
|
float fac_temp,
|
float scale_fac);
|
|
// Update the down-sampling state.
|
void UpdateDownsamplingState(UpDownAction up_down);
|
|
// Update the codec frame size and frame rate.
|
void UpdateCodecResolution();
|
|
// Return a state based on average target rate relative transition rate.
|
uint8_t RateClass(float transition_rate);
|
|
// Adjust the action selected from the table.
|
void AdjustAction();
|
|
// Covert 2 stages of 3/4 (=9/16) spatial decimation to 1/2.
|
void ConvertSpatialFractionalToWhole();
|
|
// Returns true if the new frame sizes, under the selected spatial action,
|
// are of even size.
|
bool EvenFrameSize();
|
|
// Insert latest down-sampling action into the history list.
|
void InsertLatestDownAction();
|
|
// Remove the last (first element) down-sampling action from the list.
|
void RemoveLastDownAction();
|
|
// Check constraints on the amount of down-sampling allowed.
|
void ConstrainAmountOfDownSampling();
|
|
// For going up in resolution: pick spatial or temporal action,
|
// if both actions were separately selected.
|
void PickSpatialOrTemporal();
|
|
// Select the directional (1x2 or 2x1) spatial down-sampling action.
|
void SelectSpatialDirectionMode(float transition_rate);
|
|
enum { kDownActionHistorySize = 10 };
|
|
VCMResolutionScale* qm_;
|
// Encoder rate control parameters.
|
float target_bitrate_;
|
float incoming_framerate_;
|
float per_frame_bandwidth_;
|
float buffer_level_;
|
|
// Data accumulated every ~1sec from MediaOpt.
|
float sum_target_rate_;
|
float sum_incoming_framerate_;
|
float sum_rate_MM_;
|
float sum_rate_MM_sgn_;
|
float sum_packet_loss_;
|
// Counters.
|
uint32_t frame_cnt_;
|
uint32_t frame_cnt_delta_;
|
uint32_t update_rate_cnt_;
|
uint32_t low_buffer_cnt_;
|
|
// Resolution state parameters.
|
float state_dec_factor_spatial_;
|
float state_dec_factor_temporal_;
|
|
// Quantities used for selection.
|
float avg_target_rate_;
|
float avg_incoming_framerate_;
|
float avg_ratio_buffer_low_;
|
float avg_rate_mismatch_;
|
float avg_rate_mismatch_sgn_;
|
float avg_packet_loss_;
|
EncoderState encoder_state_;
|
ResolutionAction action_;
|
// Short history of the down-sampling actions from the Initialize() state.
|
// This is needed for going up in resolution. Since the total amount of
|
// down-sampling actions are constrained, the length of the list need not be
|
// large: i.e., (4/3) ^{kDownActionHistorySize} <= kMaxDownSample.
|
ResolutionAction down_action_history_[kDownActionHistorySize];
|
int num_layers_;
|
};
|
|
// Robustness settings class.
|
|
class VCMQmRobustness : public VCMQmMethod {
|
public:
|
VCMQmRobustness();
|
~VCMQmRobustness();
|
|
virtual void Reset();
|
|
// Adjust FEC rate based on content: every ~1 sec from SetTargetRates.
|
// Returns an adjustment factor.
|
float AdjustFecFactor(uint8_t code_rate_delta,
|
float total_rate,
|
float framerate,
|
int64_t rtt_time,
|
uint8_t packet_loss);
|
|
// Set the UEP protection on/off.
|
bool SetUepProtection(uint8_t code_rate_delta,
|
float total_rate,
|
uint8_t packet_loss,
|
bool frame_type);
|
|
private:
|
// Previous state of network parameters.
|
float prev_total_rate_;
|
int64_t prev_rtt_time_;
|
uint8_t prev_packet_loss_;
|
uint8_t prev_code_rate_delta_;
|
};
|
} // namespace webrtc
|
#endif // WEBRTC_MODULES_VIDEO_CODING_QM_SELECT_H_
|