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

View File

@ -371,5 +371,16 @@ VPMSimpleSpatialResampler::TargetWidth()
return _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 } //namespace

View File

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

View File

@ -11,6 +11,7 @@
/* /*
* video_processing_impl.h * video_processing_impl.h
*/ */
#ifndef WEBRTC_MODULE_VIDEO_PROCESSING_IMPL_H #ifndef WEBRTC_MODULE_VIDEO_PROCESSING_IMPL_H
#define WEBRTC_MODULE_VIDEO_PROCESSING_IMPL_H #define WEBRTC_MODULE_VIDEO_PROCESSING_IMPL_H
@ -33,8 +34,8 @@ public:
virtual ~VideoProcessingModuleImpl(); virtual ~VideoProcessingModuleImpl();
virtual WebRtc_Word32 Version(WebRtc_Word8* version, virtual WebRtc_Word32 Version(WebRtc_Word8* version,
WebRtc_UWord32& remainingBufferInBytes, WebRtc_UWord32& remainingBufferInBytes,
WebRtc_UWord32& position) const; WebRtc_UWord32& position) const;
WebRtc_Word32 Id() const; WebRtc_Word32 Id() const;
@ -49,21 +50,21 @@ public:
FrameStats& stats); FrameStats& stats);
virtual WebRtc_Word32 Deflickering(VideoFrame& frame, virtual WebRtc_Word32 Deflickering(VideoFrame& frame,
FrameStats& stats); FrameStats& stats);
virtual WebRtc_Word32 Denoising(WebRtc_UWord8* frame, virtual WebRtc_Word32 Denoising(WebRtc_UWord8* frame,
WebRtc_UWord32 width, WebRtc_UWord32 width,
WebRtc_UWord32 height); WebRtc_UWord32 height);
virtual WebRtc_Word32 Denoising(VideoFrame& frame); virtual WebRtc_Word32 Denoising(VideoFrame& frame);
virtual WebRtc_Word32 BrightnessDetection(const WebRtc_UWord8* frame, virtual WebRtc_Word32 BrightnessDetection(const WebRtc_UWord8* frame,
WebRtc_UWord32 width, WebRtc_UWord32 width,
WebRtc_UWord32 height, WebRtc_UWord32 height,
const FrameStats& stats); const FrameStats& stats);
virtual WebRtc_Word32 BrightnessDetection(const VideoFrame& frame, virtual WebRtc_Word32 BrightnessDetection(const VideoFrame& frame,
const FrameStats& stats); const FrameStats& stats);
//Frame pre-processor functions //Frame pre-processor functions
@ -80,20 +81,26 @@ public:
virtual WebRtc_Word32 SetMaxFrameRate(WebRtc_UWord32 maxFrameRate); virtual WebRtc_Word32 SetMaxFrameRate(WebRtc_UWord32 maxFrameRate);
// Set Target Resolution: frame rate and dimension // 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 // Get decimated values: frame rate/dimension
virtual WebRtc_UWord32 DecimatedFrameRate(); virtual WebRtc_UWord32 DecimatedFrameRate();
virtual WebRtc_UWord32 DecimatedWidth() const; virtual WebRtc_UWord32 DecimatedWidth() const;
virtual WebRtc_UWord32 DecimatedHeight() const; virtual WebRtc_UWord32 DecimatedHeight() const;
// Preprocess: // Pre-process:
virtual WebRtc_Word32 PreprocessFrame(const VideoFrame* frame, VideoFrame** processedFrame); // 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; virtual VideoContentMetrics* ContentMetrics() const;
private: private:
WebRtc_Word32 _id; WebRtc_Word32 _id;
CriticalSectionWrapper& _mutex; CriticalSectionWrapper& _mutex;
VPMDeflickering _deflickering; VPMDeflickering _deflickering;
VPMDenoising _denoising; VPMDenoising _denoising;

View File

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