• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/main/source/content_metrics_processing.h"
12 
13 #include <math.h>
14 
15 #include "webrtc/modules/interface/module_common_types.h"
16 #include "webrtc/modules/video_coding/main/interface/video_coding_defines.h"
17 
18 namespace webrtc {
19 //////////////////////////////////
20 /// VCMContentMetricsProcessing //
21 //////////////////////////////////
22 
VCMContentMetricsProcessing()23 VCMContentMetricsProcessing::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()32 VCMContentMetricsProcessing::~VCMContentMetricsProcessing() {
33   delete recursive_avg_;
34   delete uniform_avg_;
35 }
36 
Reset()37 int 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)46 void 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()52 VideoContentMetrics* VCMContentMetricsProcessing::LongTermAvgData() {
53   return recursive_avg_;
54 }
55 
ShortTermAvgData()56 VideoContentMetrics* 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 = avg_motion_level_ /
62       static_cast<float>(frame_cnt_uniform_avg_);
63   uniform_avg_->spatial_pred_err = avg_spatial_level_ /
64       static_cast<float>(frame_cnt_uniform_avg_);
65   return uniform_avg_;
66 }
67 
ResetShortTermAvgData()68 void 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)75 int 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)83 int 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)94 void 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)104 void VCMContentMetricsProcessing::UpdateRecursiveAvg(
105     const VideoContentMetrics *contentMetrics) {
106 
107   // Spatial metrics: 2x2, 1x2(H), 2x1(V).
108   recursive_avg_->spatial_pred_err = (1 - recursive_avg_factor_) *
109       recursive_avg_->spatial_pred_err +
110       recursive_avg_factor_ * contentMetrics->spatial_pred_err;
111 
112   recursive_avg_->spatial_pred_err_h = (1 - recursive_avg_factor_) *
113       recursive_avg_->spatial_pred_err_h +
114       recursive_avg_factor_ * contentMetrics->spatial_pred_err_h;
115 
116   recursive_avg_->spatial_pred_err_v = (1 - recursive_avg_factor_) *
117       recursive_avg_->spatial_pred_err_v +
118       recursive_avg_factor_ * contentMetrics->spatial_pred_err_v;
119 
120   // Motion metric: Derived from NFD (normalized frame difference).
121   recursive_avg_->motion_magnitude = (1 - recursive_avg_factor_) *
122       recursive_avg_->motion_magnitude +
123       recursive_avg_factor_ * contentMetrics->motion_magnitude;
124 }
125 }  // namespace
126