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,14 +139,11 @@ 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())
@ -155,25 +152,30 @@ VPMFramePreprocessor::PreprocessFrame(const VideoFrame* frame, VideoFrame** proc
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.
// 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); WebRtc_Word32 ret = _spatialResampler->ResampleFrame(*frame, _resampledFrame);
if (ret != VPM_OK) 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)
{ {
if (*processedFrame == NULL) {
_contentMetrics = _ca->ComputeContentMetrics(frame);
} else {
_contentMetrics = _ca->ComputeContentMetrics(&_resampledFrame); _contentMetrics = _ca->ComputeContentMetrics(&_resampledFrame);
}
// Update native values: // 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
@ -80,15 +81,21 @@ 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:

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,