blob: 36e1b9bbfd6d314e4c4f22d60e1ed9ffe0573040 [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
13namespace webrtc {
14
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000015VPMFramePreprocessor::VPMFramePreprocessor()
jackychen8f9902a2015-11-26 02:59:48 -080016 : content_metrics_(nullptr),
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000017 resampled_frame_(),
18 enable_ca_(false),
jackychen8f9902a2015-11-26 02:59:48 -080019 enable_denoising_(false),
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000020 frame_cnt_(0) {
21 spatial_resampler_ = new VPMSimpleSpatialResampler();
22 ca_ = new VPMContentAnalysis(true);
23 vd_ = new VPMVideoDecimator();
jackychen8f9902a2015-11-26 02:59:48 -080024 if (enable_denoising_) {
25 denoiser_ = new VideoDenoiser();
26 } else {
27 denoiser_ = nullptr;
28 }
niklase@google.com470e71d2011-07-07 08:21:25 +000029}
30
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000031VPMFramePreprocessor::~VPMFramePreprocessor() {
32 Reset();
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000033 delete ca_;
34 delete vd_;
jackychen8f9902a2015-11-26 02:59:48 -080035 if (enable_denoising_)
36 delete denoiser_;
37 delete spatial_resampler_;
niklase@google.com470e71d2011-07-07 08:21:25 +000038}
39
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000040void VPMFramePreprocessor::Reset() {
41 ca_->Release();
42 vd_->Reset();
jackychen8f9902a2015-11-26 02:59:48 -080043 content_metrics_ = nullptr;
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000044 spatial_resampler_->Reset();
45 enable_ca_ = false;
46 frame_cnt_ = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +000047}
48
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000049void VPMFramePreprocessor::EnableTemporalDecimation(bool enable) {
50 vd_->EnableTemporalDecimation(enable);
niklase@google.com470e71d2011-07-07 08:21:25 +000051}
52
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000053void VPMFramePreprocessor::EnableContentAnalysis(bool enable) {
54 enable_ca_ = enable;
55}
56
57void VPMFramePreprocessor::SetInputFrameResampleMode(
58 VideoFrameResampling resampling_mode) {
59 spatial_resampler_->SetInputFrameResampleMode(resampling_mode);
60}
61
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000062int32_t VPMFramePreprocessor::SetTargetResolution(
63 uint32_t width, uint32_t height, uint32_t frame_rate) {
64 if ( (width == 0) || (height == 0) || (frame_rate == 0)) {
65 return VPM_PARAMETER_ERROR;
66 }
67 int32_t ret_val = 0;
68 ret_val = spatial_resampler_->SetTargetFrameSize(width, height);
69
70 if (ret_val < 0) return ret_val;
71
jackychen6e2ce6e2015-07-13 16:26:33 -070072 vd_->SetTargetFramerate(frame_rate);
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000073 return VPM_OK;
74}
75
jackychen6e2ce6e2015-07-13 16:26:33 -070076void VPMFramePreprocessor::SetTargetFramerate(int frame_rate) {
77 if (frame_rate == -1) {
78 vd_->EnableTemporalDecimation(false);
79 } else {
80 vd_->EnableTemporalDecimation(true);
81 vd_->SetTargetFramerate(frame_rate);
82 }
83}
84
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000085void VPMFramePreprocessor::UpdateIncomingframe_rate() {
86 vd_->UpdateIncomingframe_rate();
87}
88
89uint32_t VPMFramePreprocessor::Decimatedframe_rate() {
90 return vd_->Decimatedframe_rate();
91}
92
93
94uint32_t VPMFramePreprocessor::DecimatedWidth() const {
95 return spatial_resampler_->TargetWidth();
96}
97
98
99uint32_t VPMFramePreprocessor::DecimatedHeight() const {
100 return spatial_resampler_->TargetHeight();
101}
102
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700103int32_t VPMFramePreprocessor::PreprocessFrame(const VideoFrame& frame,
104 VideoFrame** processed_frame) {
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000105 if (frame.IsZeroSize()) {
106 return VPM_PARAMETER_ERROR;
107 }
108
109 vd_->UpdateIncomingframe_rate();
110
111 if (vd_->DropFrame()) {
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000112 return 1; // drop 1 frame
113 }
114
jackychen8f9902a2015-11-26 02:59:48 -0800115 // Resizing incoming frame if needed. Otherwise, remains nullptr.
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000116 // We are not allowed to resample the input frame (must make a copy of it).
jackychen8f9902a2015-11-26 02:59:48 -0800117 *processed_frame = nullptr;
118 if (denoiser_ != nullptr) {
119 denoiser_->DenoiseFrame(frame, &denoised_frame_);
120 *processed_frame = &denoised_frame_;
121 }
122
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000123 if (spatial_resampler_->ApplyResample(frame.width(), frame.height())) {
jackychen8f9902a2015-11-26 02:59:48 -0800124 int32_t ret;
125 if (enable_denoising_) {
126 ret = spatial_resampler_->ResampleFrame(denoised_frame_,
127 &resampled_frame_);
128 } else {
129 ret = spatial_resampler_->ResampleFrame(frame, &resampled_frame_);
130 }
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000131 if (ret != VPM_OK) return ret;
132 *processed_frame = &resampled_frame_;
133 }
134
135 // Perform content analysis on the frame to be encoded.
136 if (enable_ca_) {
137 // Compute new metrics every |kSkipFramesCA| frames, starting with
138 // the first frame.
139 if (frame_cnt_ % kSkipFrameCA == 0) {
jackychen8f9902a2015-11-26 02:59:48 -0800140 if (*processed_frame == nullptr) {
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000141 content_metrics_ = ca_->ComputeContentMetrics(frame);
142 } else {
jackychen8f9902a2015-11-26 02:59:48 -0800143 content_metrics_ = ca_->ComputeContentMetrics(**processed_frame);
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000144 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000145 }
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000146 }
jackychen8f9902a2015-11-26 02:59:48 -0800147 ++frame_cnt_;
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000148 return VPM_OK;
niklase@google.com470e71d2011-07-07 08:21:25 +0000149}
150
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000151VideoContentMetrics* VPMFramePreprocessor::ContentMetrics() const {
152 return content_metrics_;
niklase@google.com470e71d2011-07-07 08:21:25 +0000153}
154
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000155} // namespace