/* * 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 #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) { // Update factor for recursive averaging. recursive_avg_factor_ = static_cast(1000.0f) / static_cast(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(frame_cnt_uniform_avg_); uniform_avg_->spatial_pred_err = avg_spatial_level_ / static_cast(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