OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/modules/video_processing/frame_preprocessor.h" | 11 #include "webrtc/modules/video_processing/frame_preprocessor.h" |
12 | 12 |
| 13 #include "webrtc/modules/video_processing/video_denoiser.h" |
| 14 |
13 namespace webrtc { | 15 namespace webrtc { |
14 | 16 |
15 VPMFramePreprocessor::VPMFramePreprocessor() | 17 VPMFramePreprocessor::VPMFramePreprocessor() |
16 : content_metrics_(nullptr), | 18 : content_metrics_(nullptr), |
17 resampled_frame_(), | 19 resampled_frame_(), |
18 enable_ca_(false), | 20 enable_ca_(false), |
19 enable_denoising_(false), | |
20 frame_cnt_(0) { | 21 frame_cnt_(0) { |
21 spatial_resampler_ = new VPMSimpleSpatialResampler(); | 22 spatial_resampler_ = new VPMSimpleSpatialResampler(); |
22 ca_ = new VPMContentAnalysis(true); | 23 ca_ = new VPMContentAnalysis(true); |
23 vd_ = new VPMVideoDecimator(); | 24 vd_ = new VPMVideoDecimator(); |
24 if (enable_denoising_) { | |
25 denoiser_ = new VideoDenoiser(); | |
26 } else { | |
27 denoiser_ = nullptr; | |
28 } | |
29 } | 25 } |
30 | 26 |
31 VPMFramePreprocessor::~VPMFramePreprocessor() { | 27 VPMFramePreprocessor::~VPMFramePreprocessor() { |
32 Reset(); | 28 Reset(); |
33 delete ca_; | 29 delete ca_; |
34 delete vd_; | 30 delete vd_; |
35 if (enable_denoising_) | |
36 delete denoiser_; | |
37 delete spatial_resampler_; | 31 delete spatial_resampler_; |
38 } | 32 } |
39 | 33 |
40 void VPMFramePreprocessor::Reset() { | 34 void VPMFramePreprocessor::Reset() { |
41 ca_->Release(); | 35 ca_->Release(); |
42 vd_->Reset(); | 36 vd_->Reset(); |
43 content_metrics_ = nullptr; | 37 content_metrics_ = nullptr; |
44 spatial_resampler_->Reset(); | 38 spatial_resampler_->Reset(); |
45 enable_ca_ = false; | 39 enable_ca_ = false; |
46 frame_cnt_ = 0; | 40 frame_cnt_ = 0; |
47 } | 41 } |
48 | 42 |
49 void VPMFramePreprocessor::EnableTemporalDecimation(bool enable) { | 43 void VPMFramePreprocessor::EnableTemporalDecimation(bool enable) { |
50 vd_->EnableTemporalDecimation(enable); | 44 vd_->EnableTemporalDecimation(enable); |
51 } | 45 } |
52 | 46 |
53 void VPMFramePreprocessor::EnableContentAnalysis(bool enable) { | 47 void VPMFramePreprocessor::EnableContentAnalysis(bool enable) { |
54 enable_ca_ = enable; | 48 enable_ca_ = enable; |
55 } | 49 } |
56 | 50 |
57 void VPMFramePreprocessor::SetInputFrameResampleMode( | 51 void VPMFramePreprocessor::SetInputFrameResampleMode( |
58 VideoFrameResampling resampling_mode) { | 52 VideoFrameResampling resampling_mode) { |
59 spatial_resampler_->SetInputFrameResampleMode(resampling_mode); | 53 spatial_resampler_->SetInputFrameResampleMode(resampling_mode); |
60 } | 54 } |
61 | 55 |
62 int32_t VPMFramePreprocessor::SetTargetResolution( | 56 int32_t VPMFramePreprocessor::SetTargetResolution( |
63 uint32_t width, uint32_t height, uint32_t frame_rate) { | 57 uint32_t width, uint32_t height, uint32_t frame_rate) { |
64 if ( (width == 0) || (height == 0) || (frame_rate == 0)) { | 58 if ((width == 0) || (height == 0) || (frame_rate == 0)) { |
65 return VPM_PARAMETER_ERROR; | 59 return VPM_PARAMETER_ERROR; |
66 } | 60 } |
67 int32_t ret_val = 0; | 61 int32_t ret_val = 0; |
68 ret_val = spatial_resampler_->SetTargetFrameSize(width, height); | 62 ret_val = spatial_resampler_->SetTargetFrameSize(width, height); |
69 | 63 |
70 if (ret_val < 0) return ret_val; | 64 if (ret_val < 0) return ret_val; |
71 | 65 |
72 vd_->SetTargetFramerate(frame_rate); | 66 vd_->SetTargetFramerate(frame_rate); |
73 return VPM_OK; | 67 return VPM_OK; |
74 } | 68 } |
75 | 69 |
76 void VPMFramePreprocessor::SetTargetFramerate(int frame_rate) { | 70 void VPMFramePreprocessor::SetTargetFramerate(int frame_rate) { |
77 if (frame_rate == -1) { | 71 if (frame_rate == -1) { |
78 vd_->EnableTemporalDecimation(false); | 72 vd_->EnableTemporalDecimation(false); |
79 } else { | 73 } else { |
80 vd_->EnableTemporalDecimation(true); | 74 vd_->EnableTemporalDecimation(true); |
81 vd_->SetTargetFramerate(frame_rate); | 75 vd_->SetTargetFramerate(frame_rate); |
82 } | 76 } |
83 } | 77 } |
84 | 78 |
85 void VPMFramePreprocessor::UpdateIncomingframe_rate() { | 79 void VPMFramePreprocessor::UpdateIncomingframe_rate() { |
86 vd_->UpdateIncomingframe_rate(); | 80 vd_->UpdateIncomingframe_rate(); |
87 } | 81 } |
88 | 82 |
89 uint32_t VPMFramePreprocessor::Decimatedframe_rate() { | 83 uint32_t VPMFramePreprocessor::GetDecimatedFrameRate() { |
90 return vd_->Decimatedframe_rate(); | 84 return vd_->GetDecimatedFrameRate(); |
91 } | 85 } |
92 | 86 |
93 | 87 |
94 uint32_t VPMFramePreprocessor::DecimatedWidth() const { | 88 uint32_t VPMFramePreprocessor::GetDecimatedWidth() const { |
95 return spatial_resampler_->TargetWidth(); | 89 return spatial_resampler_->TargetWidth(); |
96 } | 90 } |
97 | 91 |
98 | 92 |
99 uint32_t VPMFramePreprocessor::DecimatedHeight() const { | 93 uint32_t VPMFramePreprocessor::GetDecimatedHeight() const { |
100 return spatial_resampler_->TargetHeight(); | 94 return spatial_resampler_->TargetHeight(); |
101 } | 95 } |
102 | 96 |
103 int32_t VPMFramePreprocessor::PreprocessFrame(const VideoFrame& frame, | 97 void VPMFramePreprocessor::EnableDenosing(bool enable) { |
104 VideoFrame** processed_frame) { | 98 denoiser_.reset(new VideoDenoiser()); |
| 99 } |
| 100 |
| 101 const VideoFrame* VPMFramePreprocessor::PreprocessFrame( |
| 102 const VideoFrame& frame) { |
105 if (frame.IsZeroSize()) { | 103 if (frame.IsZeroSize()) { |
106 return VPM_PARAMETER_ERROR; | 104 return nullptr; |
107 } | 105 } |
108 | 106 |
109 vd_->UpdateIncomingframe_rate(); | 107 vd_->UpdateIncomingframe_rate(); |
110 | |
111 if (vd_->DropFrame()) { | 108 if (vd_->DropFrame()) { |
112 return 1; // drop 1 frame | 109 return nullptr; |
113 } | 110 } |
114 | 111 |
115 // Resizing incoming frame if needed. Otherwise, remains nullptr. | 112 const VideoFrame* current_frame = &frame; |
116 // We are not allowed to resample the input frame (must make a copy of it). | 113 if (denoiser_) { |
117 *processed_frame = nullptr; | 114 denoiser_->DenoiseFrame(*current_frame, &denoised_frame_); |
118 if (denoiser_ != nullptr) { | 115 current_frame = &denoised_frame_; |
119 denoiser_->DenoiseFrame(frame, &denoised_frame_); | |
120 *processed_frame = &denoised_frame_; | |
121 } | 116 } |
122 | 117 |
123 if (spatial_resampler_->ApplyResample(frame.width(), frame.height())) { | 118 if (spatial_resampler_->ApplyResample(current_frame->width(), |
124 int32_t ret; | 119 current_frame->height())) { |
125 if (enable_denoising_) { | 120 if (spatial_resampler_->ResampleFrame(*current_frame, &resampled_frame_) != |
126 ret = spatial_resampler_->ResampleFrame(denoised_frame_, | 121 VPM_OK) { |
127 &resampled_frame_); | 122 return nullptr; |
128 } else { | |
129 ret = spatial_resampler_->ResampleFrame(frame, &resampled_frame_); | |
130 } | 123 } |
131 if (ret != VPM_OK) return ret; | 124 current_frame = &resampled_frame_; |
132 *processed_frame = &resampled_frame_; | |
133 } | 125 } |
134 | 126 |
135 // Perform content analysis on the frame to be encoded. | 127 // Perform content analysis on the frame to be encoded. |
136 if (enable_ca_) { | 128 if (enable_ca_ && frame_cnt_ % kSkipFrameCA == 0) { |
137 // Compute new metrics every |kSkipFramesCA| frames, starting with | 129 // Compute new metrics every |kSkipFramesCA| frames, starting with |
138 // the first frame. | 130 // the first frame. |
139 if (frame_cnt_ % kSkipFrameCA == 0) { | 131 content_metrics_ = ca_->ComputeContentMetrics(*current_frame); |
140 if (*processed_frame == nullptr) { | |
141 content_metrics_ = ca_->ComputeContentMetrics(frame); | |
142 } else { | |
143 content_metrics_ = ca_->ComputeContentMetrics(**processed_frame); | |
144 } | |
145 } | |
146 } | 132 } |
147 ++frame_cnt_; | 133 ++frame_cnt_; |
148 return VPM_OK; | 134 return current_frame; |
149 } | 135 } |
150 | 136 |
151 VideoContentMetrics* VPMFramePreprocessor::ContentMetrics() const { | 137 VideoContentMetrics* VPMFramePreprocessor::GetContentMetrics() const { |
152 return content_metrics_; | 138 return content_metrics_; |
153 } | 139 } |
154 | 140 |
155 } // namespace | 141 } // namespace webrtc |
OLD | NEW |