blob: fc952c0b821fc0b45b4a2ec2a6c2e7116dec3b8f [file] [log] [blame]
/*
* 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_processing/main/source/frame_preprocessor.h"
#include "webrtc/system_wrappers/interface/trace.h"
namespace webrtc {
VPMFramePreprocessor::VPMFramePreprocessor():
_id(0),
_contentMetrics(NULL),
_maxFrameRate(0),
_resampledFrame(),
_enableCA(false),
_frameCnt(0)
{
_spatialResampler = new VPMSimpleSpatialResampler();
_ca = new VPMContentAnalysis(true);
_vd = new VPMVideoDecimator();
}
VPMFramePreprocessor::~VPMFramePreprocessor()
{
Reset();
delete _spatialResampler;
delete _ca;
delete _vd;
}
int32_t
VPMFramePreprocessor::ChangeUniqueId(const int32_t id)
{
_id = id;
return VPM_OK;
}
void
VPMFramePreprocessor::Reset()
{
_ca->Release();
_vd->Reset();
_contentMetrics = NULL;
_spatialResampler->Reset();
_enableCA = false;
_frameCnt = 0;
}
void
VPMFramePreprocessor::EnableTemporalDecimation(bool enable)
{
_vd->EnableTemporalDecimation(enable);
}
void
VPMFramePreprocessor::EnableContentAnalysis(bool enable)
{
_enableCA = enable;
}
void
VPMFramePreprocessor::SetInputFrameResampleMode(VideoFrameResampling resamplingMode)
{
_spatialResampler->SetInputFrameResampleMode(resamplingMode);
}
int32_t
VPMFramePreprocessor::SetMaxFrameRate(uint32_t maxFrameRate)
{
if (maxFrameRate == 0)
{
return VPM_PARAMETER_ERROR;
}
//Max allowed frame rate
_maxFrameRate = maxFrameRate;
return _vd->SetMaxFrameRate(maxFrameRate);
}
int32_t
VPMFramePreprocessor::SetTargetResolution(uint32_t width, uint32_t height, uint32_t frameRate)
{
if ( (width == 0) || (height == 0) || (frameRate == 0))
{
return VPM_PARAMETER_ERROR;
}
int32_t retVal = 0;
retVal = _spatialResampler->SetTargetFrameSize(width, height);
if (retVal < 0)
{
return retVal;
}
retVal = _vd->SetTargetFrameRate(frameRate);
if (retVal < 0)
{
return retVal;
}
return VPM_OK;
}
void
VPMFramePreprocessor::UpdateIncomingFrameRate()
{
_vd->UpdateIncomingFrameRate();
}
uint32_t
VPMFramePreprocessor::DecimatedFrameRate()
{
return _vd->DecimatedFrameRate();
}
uint32_t
VPMFramePreprocessor::DecimatedWidth() const
{
return _spatialResampler->TargetWidth();
}
uint32_t
VPMFramePreprocessor::DecimatedHeight() const
{
return _spatialResampler->TargetHeight();
}
int32_t
VPMFramePreprocessor::PreprocessFrame(const I420VideoFrame& frame,
I420VideoFrame** processedFrame)
{
if (frame.IsZeroSize())
{
return VPM_PARAMETER_ERROR;
}
_vd->UpdateIncomingFrameRate();
if (_vd->DropFrame())
{
WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceVideo, _id,
"Drop frame due to frame rate");
return 1; // drop 1 frame
}
// Resizing incoming frame if needed. Otherwise, remains NULL.
// We are not allowed to resample the input frame (must make a copy of it).
*processedFrame = NULL;
if (_spatialResampler->ApplyResample(frame.width(), frame.height())) {
int32_t ret = _spatialResampler->ResampleFrame(frame, &_resampledFrame);
if (ret != VPM_OK)
return ret;
*processedFrame = &_resampledFrame;
}
// Perform content analysis on the frame to be encoded.
if (_enableCA)
{
// Compute new metrics every |kSkipFramesCA| frames, starting with
// the first frame.
if (_frameCnt % kSkipFrameCA == 0) {
if (*processedFrame == NULL) {
_contentMetrics = _ca->ComputeContentMetrics(frame);
} else {
_contentMetrics = _ca->ComputeContentMetrics(_resampledFrame);
}
}
++_frameCnt;
}
return VPM_OK;
}
VideoContentMetrics*
VPMFramePreprocessor::ContentMetrics() const
{
return _contentMetrics;
}
} // namespace