video_processing: Adding logic to avoid a memcpy when not required

Review URL: http://webrtc-codereview.appspot.com/255002

git-svn-id: http://webrtc.googlecode.com/svn/trunk@858 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
mikhal@webrtc.org 2011-11-01 16:44:24 +00:00
parent 0ab521f754
commit c4ab8706f4
5 changed files with 63 additions and 32 deletions

View File

@ -139,41 +139,43 @@ VPMFramePreprocessor::DecimatedHeight() const
WebRtc_Word32
VPMFramePreprocessor::PreprocessFrame(const VideoFrame* frame, VideoFrame** processedFrame)
{
if (frame == NULL)
{
return VPM_PARAMETER_ERROR;
}
else if (frame->Height() == 0 || frame->Width() == 0)
if (frame == NULL || frame->Height() == 0 || frame->Width() == 0)
{
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
return 1; // drop 1 frame
}
//Resizing incoming frame.
// Note that we must make a copy of it. We are not allowed to resample the input frame.
WebRtc_Word32 ret = _spatialResampler->ResampleFrame(*frame, _resampledFrame);
if (ret != VPM_OK)
{
// Resizing incoming frame if needed.
// Note that we must make a copy of it.
// We are not allowed to resample the input frame.
*processedFrame = NULL;
if (_spatialResampler->ApplyResample(frame->Width(), frame->Height())) {
WebRtc_Word32 ret = _spatialResampler->ResampleFrame(*frame, _resampledFrame);
if (ret != VPM_OK)
return ret;
*processedFrame = &_resampledFrame;
}
*processedFrame = &_resampledFrame;
// Perform content analysis on the resampled frame
// Perform content analysis on the frame to be encoded
if (_enableCA)
{
_contentMetrics = _ca->ComputeContentMetrics(&_resampledFrame);
//Update native values:
if (*processedFrame == NULL) {
_contentMetrics = _ca->ComputeContentMetrics(frame);
} else {
_contentMetrics = _ca->ComputeContentMetrics(&_resampledFrame);
}
// Update native values:
_contentMetrics->nativeHeight = frame->Height();
_contentMetrics->nativeWidth = frame->Width();
_contentMetrics->nativeFrameRate = _maxFrameRate; // max value as set by user
// Max value as set by user
_contentMetrics->nativeFrameRate = _maxFrameRate;
}
return VPM_OK;
}

View File

@ -371,5 +371,16 @@ VPMSimpleSpatialResampler::TargetWidth()
return _targetWidth;
}
bool
VPMSimpleSpatialResampler::ApplyResample(WebRtc_UWord32 width,
WebRtc_UWord32 height)
{
if ((width == _targetWidth && height == _targetHeight) ||
_resamplingMode == kNoRescaling)
return false;
else
return true;
}
} //namespace

View File

@ -39,6 +39,7 @@ public:
virtual WebRtc_UWord32 TargetWidth() = 0;
virtual WebRtc_UWord32 TargetHeight() = 0;
virtual WebRtc_Word32 Release() = 0;
virtual bool ApplyResample(WebRtc_UWord32 width, WebRtc_UWord32 height) = 0;
};
class VPMSimpleSpatialResampler : public VPMSpatialResampler
@ -55,6 +56,7 @@ public:
virtual WebRtc_UWord32 TargetWidth();
virtual WebRtc_UWord32 TargetHeight();
virtual WebRtc_Word32 Release();
virtual bool ApplyResample(WebRtc_UWord32 width, WebRtc_UWord32 height);
private:
WebRtc_Word32 UpsampleFrame(const VideoFrame& inFrame, VideoFrame& outFrame);

View File

@ -11,6 +11,7 @@
/*
* video_processing_impl.h
*/
#ifndef WEBRTC_MODULE_VIDEO_PROCESSING_IMPL_H
#define WEBRTC_MODULE_VIDEO_PROCESSING_IMPL_H
@ -33,8 +34,8 @@ public:
virtual ~VideoProcessingModuleImpl();
virtual WebRtc_Word32 Version(WebRtc_Word8* version,
WebRtc_UWord32& remainingBufferInBytes,
WebRtc_UWord32& position) const;
WebRtc_UWord32& remainingBufferInBytes,
WebRtc_UWord32& position) const;
WebRtc_Word32 Id() const;
@ -49,21 +50,21 @@ public:
FrameStats& stats);
virtual WebRtc_Word32 Deflickering(VideoFrame& frame,
FrameStats& stats);
FrameStats& stats);
virtual WebRtc_Word32 Denoising(WebRtc_UWord8* frame,
WebRtc_UWord32 width,
WebRtc_UWord32 height);
WebRtc_UWord32 width,
WebRtc_UWord32 height);
virtual WebRtc_Word32 Denoising(VideoFrame& frame);
virtual WebRtc_Word32 BrightnessDetection(const WebRtc_UWord8* frame,
WebRtc_UWord32 width,
WebRtc_UWord32 height,
const FrameStats& stats);
WebRtc_UWord32 width,
WebRtc_UWord32 height,
const FrameStats& stats);
virtual WebRtc_Word32 BrightnessDetection(const VideoFrame& frame,
const FrameStats& stats);
const FrameStats& stats);
//Frame pre-processor functions
@ -80,20 +81,26 @@ public:
virtual WebRtc_Word32 SetMaxFrameRate(WebRtc_UWord32 maxFrameRate);
// Set Target Resolution: frame rate and dimension
virtual WebRtc_Word32 SetTargetResolution(WebRtc_UWord32 width, WebRtc_UWord32 height, WebRtc_UWord32 frameRate);
virtual WebRtc_Word32 SetTargetResolution(WebRtc_UWord32 width,
WebRtc_UWord32 height,
WebRtc_UWord32 frameRate);
// Get decimated values: frame rate/dimension
virtual WebRtc_UWord32 DecimatedFrameRate();
virtual WebRtc_UWord32 DecimatedWidth() const;
virtual WebRtc_UWord32 DecimatedHeight() const;
// Preprocess:
virtual WebRtc_Word32 PreprocessFrame(const VideoFrame* frame, VideoFrame** processedFrame);
// Pre-process:
// Pre-process incoming frame: Sample when needed and compute content metrics
// when enable.
// If no resampling takes place - processedFrame is set to NULL.
virtual WebRtc_Word32 PreprocessFrame(const VideoFrame* frame,
VideoFrame** processedFrame);
virtual VideoContentMetrics* ContentMetrics() const;
private:
WebRtc_Word32 _id;
CriticalSectionWrapper& _mutex;
WebRtc_Word32 _id;
CriticalSectionWrapper& _mutex;
VPMDeflickering _deflickering;
VPMDenoising _denoising;

View File

@ -585,6 +585,11 @@ void ViEEncoder::DeliverFrame(int id, webrtc::VideoFrame& videoFrame,
VideoContentMetrics* contentMetrics = NULL;
contentMetrics = _vpm.ContentMetrics();
// frame was not sampled => use original
if (decimatedFrame == NULL) {
decimatedFrame = &videoFrame;
}
if (_vcm.AddVideoFrame
(*decimatedFrame, contentMetrics, &codecSpecificInfo) != VCM_OK)
{
@ -609,6 +614,10 @@ void ViEEncoder::DeliverFrame(int id, webrtc::VideoFrame& videoFrame,
"%s: Error preprocessing frame %u", __FUNCTION__, videoFrame.TimeStamp());
return;
}
// frame was not sampled => use original
if (decimatedFrame == NULL) {
decimatedFrame = &videoFrame;
}
if (_vcm.AddVideoFrame(*decimatedFrame) != VCM_OK)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,