1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 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 #include "webrtc/modules/video_coding/content_metrics_processing.h" 12 13 #include <math.h> 14 15 #include "webrtc/modules/include/module_common_types.h" 16 #include "webrtc/modules/video_coding/include/video_coding_defines.h" 17 18 namespace webrtc { 19 ////////////////////////////////// 20 /// VCMContentMetricsProcessing // 21 ////////////////////////////////// 22 VCMContentMetricsProcessing()23VCMContentMetricsProcessing::VCMContentMetricsProcessing() 24 : recursive_avg_factor_(1 / 150.0f), // matched to 30fps. 25 frame_cnt_uniform_avg_(0), 26 avg_motion_level_(0.0f), 27 avg_spatial_level_(0.0f) { 28 recursive_avg_ = new VideoContentMetrics(); 29 uniform_avg_ = new VideoContentMetrics(); 30 } 31 ~VCMContentMetricsProcessing()32VCMContentMetricsProcessing::~VCMContentMetricsProcessing() { 33 delete recursive_avg_; 34 delete uniform_avg_; 35 } 36 Reset()37int VCMContentMetricsProcessing::Reset() { 38 recursive_avg_->Reset(); 39 uniform_avg_->Reset(); 40 frame_cnt_uniform_avg_ = 0; 41 avg_motion_level_ = 0.0f; 42 avg_spatial_level_ = 0.0f; 43 return VCM_OK; 44 } 45 UpdateFrameRate(uint32_t frameRate)46void VCMContentMetricsProcessing::UpdateFrameRate(uint32_t frameRate) { 47 // Update factor for recursive averaging. 48 recursive_avg_factor_ = static_cast<float>(1000.0f) / 49 static_cast<float>(frameRate * kQmMinIntervalMs); 50 } 51 LongTermAvgData()52VideoContentMetrics* VCMContentMetricsProcessing::LongTermAvgData() { 53 return recursive_avg_; 54 } 55 ShortTermAvgData()56VideoContentMetrics* VCMContentMetricsProcessing::ShortTermAvgData() { 57 if (frame_cnt_uniform_avg_ == 0) { 58 return NULL; 59 } 60 // Two metrics are used: motion and spatial level. 61 uniform_avg_->motion_magnitude = 62 avg_motion_level_ / static_cast<float>(frame_cnt_uniform_avg_); 63 uniform_avg_->spatial_pred_err = 64 avg_spatial_level_ / static_cast<float>(frame_cnt_uniform_avg_); 65 return uniform_avg_; 66 } 67 ResetShortTermAvgData()68void VCMContentMetricsProcessing::ResetShortTermAvgData() { 69 // Reset. 70 avg_motion_level_ = 0.0f; 71 avg_spatial_level_ = 0.0f; 72 frame_cnt_uniform_avg_ = 0; 73 } 74 UpdateContentData(const VideoContentMetrics * contentMetrics)75int VCMContentMetricsProcessing::UpdateContentData( 76 const VideoContentMetrics* contentMetrics) { 77 if (contentMetrics == NULL) { 78 return VCM_OK; 79 } 80 return ProcessContent(contentMetrics); 81 } 82 ProcessContent(const VideoContentMetrics * contentMetrics)83int VCMContentMetricsProcessing::ProcessContent( 84 const VideoContentMetrics* contentMetrics) { 85 // Update the recursive averaged metrics: average is over longer window 86 // of time: over QmMinIntervalMs ms. 87 UpdateRecursiveAvg(contentMetrics); 88 // Update the uniform averaged metrics: average is over shorter window 89 // of time: based on ~RTCP reports. 90 UpdateUniformAvg(contentMetrics); 91 return VCM_OK; 92 } 93 UpdateUniformAvg(const VideoContentMetrics * contentMetrics)94void VCMContentMetricsProcessing::UpdateUniformAvg( 95 const VideoContentMetrics* contentMetrics) { 96 // Update frame counter. 97 frame_cnt_uniform_avg_ += 1; 98 // Update averaged metrics: motion and spatial level are used. 99 avg_motion_level_ += contentMetrics->motion_magnitude; 100 avg_spatial_level_ += contentMetrics->spatial_pred_err; 101 return; 102 } 103 UpdateRecursiveAvg(const VideoContentMetrics * contentMetrics)104void VCMContentMetricsProcessing::UpdateRecursiveAvg( 105 const VideoContentMetrics* contentMetrics) { 106 // Spatial metrics: 2x2, 1x2(H), 2x1(V). 107 recursive_avg_->spatial_pred_err = 108 (1 - recursive_avg_factor_) * recursive_avg_->spatial_pred_err + 109 recursive_avg_factor_ * contentMetrics->spatial_pred_err; 110 111 recursive_avg_->spatial_pred_err_h = 112 (1 - recursive_avg_factor_) * recursive_avg_->spatial_pred_err_h + 113 recursive_avg_factor_ * contentMetrics->spatial_pred_err_h; 114 115 recursive_avg_->spatial_pred_err_v = 116 (1 - recursive_avg_factor_) * recursive_avg_->spatial_pred_err_v + 117 recursive_avg_factor_ * contentMetrics->spatial_pred_err_v; 118 119 // Motion metric: Derived from NFD (normalized frame difference). 120 recursive_avg_->motion_magnitude = 121 (1 - recursive_avg_factor_) * recursive_avg_->motion_magnitude + 122 recursive_avg_factor_ * contentMetrics->motion_magnitude; 123 } 124 } // namespace webrtc 125