blob: 7393af856bb8d685c140adb53dec2db89c74ff90 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
marpan@webrtc.org9d76b4e2012-02-28 23:39:31 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Henrik Kjellander0f59a882015-11-18 22:31:24 +010011#include "webrtc/modules/video_processing/frame_preprocessor.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
mflodmana8565422015-12-07 01:09:52 -080013#include "webrtc/modules/video_processing/video_denoiser.h"
14
niklase@google.com470e71d2011-07-07 08:21:25 +000015namespace webrtc {
16
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000017VPMFramePreprocessor::VPMFramePreprocessor()
jackychen8f9902a2015-11-26 02:59:48 -080018 : content_metrics_(nullptr),
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000019 resampled_frame_(),
20 enable_ca_(false),
21 frame_cnt_(0) {
22 spatial_resampler_ = new VPMSimpleSpatialResampler();
23 ca_ = new VPMContentAnalysis(true);
24 vd_ = new VPMVideoDecimator();
nisse90c335a2016-04-27 00:59:22 -070025 EnableDenoising(false);
jackychenafaae0d2016-04-12 23:02:55 -070026 denoised_frame_toggle_ = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +000027}
28
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000029VPMFramePreprocessor::~VPMFramePreprocessor() {
30 Reset();
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000031 delete ca_;
32 delete vd_;
jackychen8f9902a2015-11-26 02:59:48 -080033 delete spatial_resampler_;
niklase@google.com470e71d2011-07-07 08:21:25 +000034}
35
mflodman99ab9442015-12-07 22:54:50 -080036void VPMFramePreprocessor::Reset() {
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000037 ca_->Release();
38 vd_->Reset();
jackychen8f9902a2015-11-26 02:59:48 -080039 content_metrics_ = nullptr;
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000040 spatial_resampler_->Reset();
41 enable_ca_ = false;
42 frame_cnt_ = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +000043}
44
mflodman99ab9442015-12-07 22:54:50 -080045void VPMFramePreprocessor::EnableTemporalDecimation(bool enable) {
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000046 vd_->EnableTemporalDecimation(enable);
niklase@google.com470e71d2011-07-07 08:21:25 +000047}
48
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000049void VPMFramePreprocessor::EnableContentAnalysis(bool enable) {
50 enable_ca_ = enable;
51}
52
mflodman99ab9442015-12-07 22:54:50 -080053void VPMFramePreprocessor::SetInputFrameResampleMode(
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000054 VideoFrameResampling resampling_mode) {
55 spatial_resampler_->SetInputFrameResampleMode(resampling_mode);
56}
57
mflodman99ab9442015-12-07 22:54:50 -080058int32_t VPMFramePreprocessor::SetTargetResolution(uint32_t width,
59 uint32_t height,
60 uint32_t frame_rate) {
mflodmana8565422015-12-07 01:09:52 -080061 if ((width == 0) || (height == 0) || (frame_rate == 0)) {
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000062 return VPM_PARAMETER_ERROR;
63 }
64 int32_t ret_val = 0;
65 ret_val = spatial_resampler_->SetTargetFrameSize(width, height);
66
mflodman99ab9442015-12-07 22:54:50 -080067 if (ret_val < 0)
68 return ret_val;
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000069
jackychen6e2ce6e2015-07-13 16:26:33 -070070 vd_->SetTargetFramerate(frame_rate);
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000071 return VPM_OK;
72}
73
74void VPMFramePreprocessor::UpdateIncomingframe_rate() {
75 vd_->UpdateIncomingframe_rate();
76}
77
mflodmana8565422015-12-07 01:09:52 -080078uint32_t VPMFramePreprocessor::GetDecimatedFrameRate() {
79 return vd_->GetDecimatedFrameRate();
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000080}
81
mflodmana8565422015-12-07 01:09:52 -080082uint32_t VPMFramePreprocessor::GetDecimatedWidth() const {
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000083 return spatial_resampler_->TargetWidth();
84}
85
mflodmana8565422015-12-07 01:09:52 -080086uint32_t VPMFramePreprocessor::GetDecimatedHeight() const {
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000087 return spatial_resampler_->TargetHeight();
88}
89
nisse90c335a2016-04-27 00:59:22 -070090void VPMFramePreprocessor::EnableDenoising(bool enable) {
jackychenf0b8a372016-01-19 18:18:52 -080091 if (enable) {
92 denoiser_.reset(new VideoDenoiser(true));
93 } else {
94 denoiser_.reset();
95 }
mflodmana8565422015-12-07 01:09:52 -080096}
97
98const VideoFrame* VPMFramePreprocessor::PreprocessFrame(
99 const VideoFrame& frame) {
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000100 if (frame.IsZeroSize()) {
mflodmana8565422015-12-07 01:09:52 -0800101 return nullptr;
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000102 }
103
104 vd_->UpdateIncomingframe_rate();
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000105 if (vd_->DropFrame()) {
mflodmana8565422015-12-07 01:09:52 -0800106 return nullptr;
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000107 }
108
mflodmana8565422015-12-07 01:09:52 -0800109 const VideoFrame* current_frame = &frame;
110 if (denoiser_) {
jackychenafaae0d2016-04-12 23:02:55 -0700111 VideoFrame* denoised_frame = &denoised_frame_[0];
112 VideoFrame* denoised_frame_prev = &denoised_frame_[1];
113 // Swap the buffer to save one memcpy in DenoiseFrame.
114 if (denoised_frame_toggle_) {
115 denoised_frame = &denoised_frame_[1];
116 denoised_frame_prev = &denoised_frame_[0];
117 }
118 // Invert the flag.
119 denoised_frame_toggle_ ^= 1;
120 denoiser_->DenoiseFrame(*current_frame, denoised_frame, denoised_frame_prev,
121 true);
122 current_frame = denoised_frame;
jackychen8f9902a2015-11-26 02:59:48 -0800123 }
124
mflodmana8565422015-12-07 01:09:52 -0800125 if (spatial_resampler_->ApplyResample(current_frame->width(),
mflodman99ab9442015-12-07 22:54:50 -0800126 current_frame->height())) {
mflodmana8565422015-12-07 01:09:52 -0800127 if (spatial_resampler_->ResampleFrame(*current_frame, &resampled_frame_) !=
128 VPM_OK) {
129 return nullptr;
jackychen8f9902a2015-11-26 02:59:48 -0800130 }
mflodmana8565422015-12-07 01:09:52 -0800131 current_frame = &resampled_frame_;
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000132 }
133
134 // Perform content analysis on the frame to be encoded.
mflodmana8565422015-12-07 01:09:52 -0800135 if (enable_ca_ && frame_cnt_ % kSkipFrameCA == 0) {
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000136 // Compute new metrics every |kSkipFramesCA| frames, starting with
137 // the first frame.
mflodmana8565422015-12-07 01:09:52 -0800138 content_metrics_ = ca_->ComputeContentMetrics(*current_frame);
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000139 }
jackychen8f9902a2015-11-26 02:59:48 -0800140 ++frame_cnt_;
mflodmana8565422015-12-07 01:09:52 -0800141 return current_frame;
niklase@google.com470e71d2011-07-07 08:21:25 +0000142}
143
mflodmana8565422015-12-07 01:09:52 -0800144VideoContentMetrics* VPMFramePreprocessor::GetContentMetrics() const {
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000145 return content_metrics_;
niklase@google.com470e71d2011-07-07 08:21:25 +0000146}
147
mflodmana8565422015-12-07 01:09:52 -0800148} // namespace webrtc