3ad9c18843
Added metrics averaged over intervals of the loss/bandwidth reports, to be used for adjustment of robustness settings. Separated this set from the (global) metrics used for resolution adaptation. Some code cleanup in content_metrics.cc/.h. Review URL: http://webrtc-codereview.appspot.com/52002 git-svn-id: http://webrtc.googlecode.com/svn/trunk@125 4adac7df-926f-26a2-2b94-8c16560cd09d
214 lines
5.9 KiB
C++
214 lines
5.9 KiB
C++
/*
|
|
* Copyright (c) 2011 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 "content_metrics_processing.h"
|
|
#include "tick_time.h"
|
|
#include "module_common_types.h"
|
|
#include "video_coding_defines.h"
|
|
|
|
#include <math.h>
|
|
|
|
namespace webrtc {
|
|
|
|
//////////////////////////////////
|
|
/// VCMContentMetricsProcessing //
|
|
//////////////////////////////////
|
|
|
|
VCMContentMetricsProcessing::VCMContentMetricsProcessing():
|
|
_frameRate(0),
|
|
_recAvgFactor(1 / 150.0f), // matched to 30fps
|
|
_frameCntRecursiveAvg(0),
|
|
_frameCntUniformAvg(0),
|
|
_avgMotionLevel(0.0f),
|
|
_avgSpatialLevel(0.0f)
|
|
{
|
|
_recursiveAvg = new VideoContentMetrics();
|
|
_uniformAvg = new VideoContentMetrics();
|
|
}
|
|
|
|
VCMContentMetricsProcessing::~VCMContentMetricsProcessing()
|
|
{
|
|
delete _recursiveAvg;
|
|
delete _uniformAvg;
|
|
}
|
|
|
|
WebRtc_Word32
|
|
VCMContentMetricsProcessing::Reset()
|
|
{
|
|
_recursiveAvg->Reset();
|
|
_uniformAvg->Reset();
|
|
_frameRate = 0;
|
|
_frameCntRecursiveAvg = 0;
|
|
_frameCntUniformAvg = 0;
|
|
_avgMotionLevel = 0.0f;
|
|
_avgSpatialLevel = 0.0f;
|
|
return VCM_OK;
|
|
}
|
|
|
|
void
|
|
VCMContentMetricsProcessing::UpdateFrameRate(WebRtc_UWord32 frameRate)
|
|
{
|
|
_frameRate = frameRate;
|
|
// Update factor for recursive averaging.
|
|
_recAvgFactor = (float) 1000.0f / ((float)(_frameRate * kQmMinIntervalMs));
|
|
|
|
}
|
|
|
|
VideoContentMetrics*
|
|
VCMContentMetricsProcessing::LongTermAvgData()
|
|
{
|
|
if (_frameCntRecursiveAvg == 0)
|
|
{
|
|
return NULL;
|
|
}
|
|
return _recursiveAvg;
|
|
}
|
|
|
|
VideoContentMetrics*
|
|
VCMContentMetricsProcessing::ShortTermAvgData()
|
|
{
|
|
if (_frameCntUniformAvg == 0)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
// Two metrics are used: motion and spatial level.
|
|
_uniformAvg->motionMagnitudeNZ = _avgMotionLevel /
|
|
(float)(_frameCntUniformAvg);
|
|
_uniformAvg->spatialPredErr = _avgSpatialLevel /
|
|
(float)(_frameCntUniformAvg);
|
|
|
|
return _uniformAvg;
|
|
}
|
|
|
|
void
|
|
VCMContentMetricsProcessing::ResetShortTermAvgData()
|
|
{
|
|
// Reset
|
|
_avgMotionLevel = 0.0f;
|
|
_avgSpatialLevel = 0.0f;
|
|
_frameCntUniformAvg = 0;
|
|
}
|
|
|
|
WebRtc_Word32
|
|
VCMContentMetricsProcessing::UpdateContentData(const VideoContentMetrics *contentMetrics)
|
|
{
|
|
if (contentMetrics == NULL)
|
|
{
|
|
return VCM_OK;
|
|
}
|
|
return ProcessContent(contentMetrics);
|
|
|
|
}
|
|
|
|
WebRtc_UWord32
|
|
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
|
|
_frameCntUniformAvg += 1;
|
|
|
|
// Update averaged metrics: motion and spatial level are used.
|
|
_avgMotionLevel += contentMetrics->motionMagnitudeNZ;
|
|
_avgSpatialLevel += contentMetrics->spatialPredErr;
|
|
|
|
return;
|
|
|
|
}
|
|
void
|
|
VCMContentMetricsProcessing::UpdateRecursiveAvg(const VideoContentMetrics *contentMetrics)
|
|
{
|
|
|
|
// Threshold for size of zero motion cluster:
|
|
// Use for updating 3 motion vector derived metrics:
|
|
// motion magnitude, cluster distortion, and horizontalness.
|
|
float nonZeroMvThr = 0.1f;
|
|
|
|
float tmpRecAvgFactor = _recAvgFactor;
|
|
|
|
// Take value as is for first frame (no motion search in frame zero).
|
|
if (_frameCntRecursiveAvg < 1)
|
|
{
|
|
tmpRecAvgFactor = 1;
|
|
}
|
|
|
|
_recursiveAvg->motionPredErr = (1 - tmpRecAvgFactor) *
|
|
_recursiveAvg->motionPredErr +
|
|
tmpRecAvgFactor * contentMetrics->motionPredErr;
|
|
|
|
_recursiveAvg->sizeZeroMotion = (1 - tmpRecAvgFactor) *
|
|
_recursiveAvg->sizeZeroMotion +
|
|
tmpRecAvgFactor * contentMetrics->sizeZeroMotion;
|
|
|
|
_recursiveAvg->spatialPredErr = (1 - tmpRecAvgFactor) *
|
|
_recursiveAvg->spatialPredErr +
|
|
tmpRecAvgFactor * contentMetrics->spatialPredErr;
|
|
|
|
_recursiveAvg->spatialPredErrH = (1 - tmpRecAvgFactor) *
|
|
_recursiveAvg->spatialPredErrH +
|
|
tmpRecAvgFactor * contentMetrics->spatialPredErrH;
|
|
|
|
_recursiveAvg->spatialPredErrV = (1 - tmpRecAvgFactor) *
|
|
_recursiveAvg->spatialPredErrV +
|
|
tmpRecAvgFactor * contentMetrics->spatialPredErrV;
|
|
|
|
// motionMag metric is derived from NFD (normalized frame difference).
|
|
if (kNfdMetric == 1)
|
|
{
|
|
_recursiveAvg->motionMagnitudeNZ = (1 - tmpRecAvgFactor) *
|
|
_recursiveAvg->motionMagnitudeNZ +
|
|
tmpRecAvgFactor * contentMetrics->motionMagnitudeNZ;
|
|
}
|
|
|
|
if (contentMetrics->sizeZeroMotion > nonZeroMvThr)
|
|
{
|
|
_recursiveAvg->motionClusterDistortion = (1 - tmpRecAvgFactor) *
|
|
_recursiveAvg->motionClusterDistortion +
|
|
tmpRecAvgFactor *contentMetrics->motionClusterDistortion;
|
|
|
|
_recursiveAvg->motionHorizontalness = (1 - _recAvgFactor) *
|
|
_recursiveAvg->motionHorizontalness +
|
|
tmpRecAvgFactor * contentMetrics->motionHorizontalness;
|
|
|
|
// motionMag metric is derived from motion vectors.
|
|
if (kNfdMetric == 0)
|
|
{
|
|
_recursiveAvg->motionMagnitudeNZ = (1 - tmpRecAvgFactor) *
|
|
_recursiveAvg->motionMagnitudeNZ +
|
|
tmpRecAvgFactor * contentMetrics->motionMagnitudeNZ;
|
|
}
|
|
}
|
|
|
|
// Update native values:
|
|
// TODO (marpan): we don't need to update this every frame.
|
|
_recursiveAvg->nativeHeight = contentMetrics->nativeHeight;
|
|
_recursiveAvg->nativeWidth = contentMetrics->nativeWidth;
|
|
_recursiveAvg->nativeFrameRate = contentMetrics->nativeFrameRate;
|
|
|
|
_frameCntRecursiveAvg++;
|
|
|
|
return;
|
|
}
|
|
} //end of namespace
|