Home | History | Annotate | Download | only in source
      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 
     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 
     32 VCMContentMetricsProcessing::~VCMContentMetricsProcessing() {
     33   delete recursive_avg_;
     34   delete uniform_avg_;
     35 }
     36 
     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 
     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 
     52 VideoContentMetrics* VCMContentMetricsProcessing::LongTermAvgData() {
     53   return recursive_avg_;
     54 }
     55 
     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 
     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 
     75 int VCMContentMetricsProcessing::UpdateContentData(
     76     const VideoContentMetrics *contentMetrics) {
     77   if (contentMetrics == NULL) {
     78     return VCM_OK;
     79   }
     80   return ProcessContent(contentMetrics);
     81 }
     82 
     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 
     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 
    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