| /* |
| * 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. |
| */ |
| |
| #include "webrtc/modules/video_coding/content_metrics_processing.h" |
| |
| #include <math.h> |
| |
| #include "webrtc/modules/include/module_common_types.h" |
| #include "webrtc/modules/video_coding/include/video_coding_defines.h" |
| |
| namespace webrtc { |
| ////////////////////////////////// |
| /// VCMContentMetricsProcessing // |
| ////////////////////////////////// |
| |
| VCMContentMetricsProcessing::VCMContentMetricsProcessing() |
| : recursive_avg_factor_(1 / 150.0f), // matched to 30fps. |
| frame_cnt_uniform_avg_(0), |
| avg_motion_level_(0.0f), |
| avg_spatial_level_(0.0f) { |
| recursive_avg_ = new VideoContentMetrics(); |
| uniform_avg_ = new VideoContentMetrics(); |
| } |
| |
| VCMContentMetricsProcessing::~VCMContentMetricsProcessing() { |
| delete recursive_avg_; |
| delete uniform_avg_; |
| } |
| |
| int VCMContentMetricsProcessing::Reset() { |
| recursive_avg_->Reset(); |
| uniform_avg_->Reset(); |
| frame_cnt_uniform_avg_ = 0; |
| avg_motion_level_ = 0.0f; |
| avg_spatial_level_ = 0.0f; |
| return VCM_OK; |
| } |
| |
| void VCMContentMetricsProcessing::UpdateFrameRate(uint32_t frameRate) { |
| if (frameRate == 0) |
| frameRate = 1; |
| // Update factor for recursive averaging. |
| recursive_avg_factor_ = static_cast<float>(1000.0f) / |
| static_cast<float>(frameRate * kQmMinIntervalMs); |
| } |
| |
| VideoContentMetrics* VCMContentMetricsProcessing::LongTermAvgData() { |
| return recursive_avg_; |
| } |
| |
| VideoContentMetrics* VCMContentMetricsProcessing::ShortTermAvgData() { |
| if (frame_cnt_uniform_avg_ == 0) { |
| return NULL; |
| } |
| // Two metrics are used: motion and spatial level. |
| uniform_avg_->motion_magnitude = |
| avg_motion_level_ / static_cast<float>(frame_cnt_uniform_avg_); |
| uniform_avg_->spatial_pred_err = |
| avg_spatial_level_ / static_cast<float>(frame_cnt_uniform_avg_); |
| return uniform_avg_; |
| } |
| |
| void VCMContentMetricsProcessing::ResetShortTermAvgData() { |
| // Reset. |
| avg_motion_level_ = 0.0f; |
| avg_spatial_level_ = 0.0f; |
| frame_cnt_uniform_avg_ = 0; |
| } |
| |
| int VCMContentMetricsProcessing::UpdateContentData( |
| const VideoContentMetrics* contentMetrics) { |
| if (contentMetrics == NULL) { |
| return VCM_OK; |
| } |
| return ProcessContent(contentMetrics); |
| } |
| |
| int VCMContentMetricsProcessing::ProcessContent( |
| const VideoContentMetrics* contentMetrics) { |
| // Update the recursive averaged metrics: average is over longer window |
| // of time: over QmMinIntervalMs ms. |
| UpdateRecursiveAvg(contentMetrics); |
| // Update the uniform averaged metrics: average is over shorter window |
| // of time: based on ~RTCP reports. |
| UpdateUniformAvg(contentMetrics); |
| return VCM_OK; |
| } |
| |
| void VCMContentMetricsProcessing::UpdateUniformAvg( |
| const VideoContentMetrics* contentMetrics) { |
| // Update frame counter. |
| frame_cnt_uniform_avg_ += 1; |
| // Update averaged metrics: motion and spatial level are used. |
| avg_motion_level_ += contentMetrics->motion_magnitude; |
| avg_spatial_level_ += contentMetrics->spatial_pred_err; |
| return; |
| } |
| |
| void VCMContentMetricsProcessing::UpdateRecursiveAvg( |
| const VideoContentMetrics* contentMetrics) { |
| // Spatial metrics: 2x2, 1x2(H), 2x1(V). |
| recursive_avg_->spatial_pred_err = |
| (1 - recursive_avg_factor_) * recursive_avg_->spatial_pred_err + |
| recursive_avg_factor_ * contentMetrics->spatial_pred_err; |
| |
| recursive_avg_->spatial_pred_err_h = |
| (1 - recursive_avg_factor_) * recursive_avg_->spatial_pred_err_h + |
| recursive_avg_factor_ * contentMetrics->spatial_pred_err_h; |
| |
| recursive_avg_->spatial_pred_err_v = |
| (1 - recursive_avg_factor_) * recursive_avg_->spatial_pred_err_v + |
| recursive_avg_factor_ * contentMetrics->spatial_pred_err_v; |
| |
| // Motion metric: Derived from NFD (normalized frame difference). |
| recursive_avg_->motion_magnitude = |
| (1 - recursive_avg_factor_) * recursive_avg_->motion_magnitude + |
| recursive_avg_factor_ * contentMetrics->motion_magnitude; |
| } |
| } // namespace webrtc |