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/video_processing_impl.h" | 11 #include "webrtc/modules/video_processing/video_processing_impl.h" |
12 | 12 |
13 #include <assert.h> | 13 #include <assert.h> |
14 | 14 |
15 #include "webrtc/base/checks.h" | 15 #include "webrtc/base/checks.h" |
16 #include "webrtc/base/logging.h" | 16 #include "webrtc/base/logging.h" |
17 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" | 17 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" |
18 | 18 |
19 namespace webrtc { | 19 namespace webrtc { |
20 | 20 |
21 namespace { | |
22 | |
23 int GetSubSamplingFactor(int width, int height) { | |
24 if (width * height >= 640 * 480) { | |
25 return 3; | |
26 } else if (width * height >= 352 * 288) { | |
27 return 2; | |
28 } else if (width * height >= 176 * 144) { | |
29 return 1; | |
30 } else { | |
31 return 0; | |
32 } | |
33 } | |
34 } // namespace | |
35 | |
36 VideoProcessing* VideoProcessing::Create() { | 21 VideoProcessing* VideoProcessing::Create() { |
37 return new VideoProcessingImpl(); | 22 return new VideoProcessingImpl(); |
38 } | 23 } |
39 | 24 |
40 VideoProcessingImpl::VideoProcessingImpl() {} | 25 VideoProcessingImpl::VideoProcessingImpl() {} |
41 VideoProcessingImpl::~VideoProcessingImpl() {} | 26 VideoProcessingImpl::~VideoProcessingImpl() {} |
42 | 27 |
43 void VideoProcessing::GetFrameStats(const VideoFrame& frame, | |
44 FrameStats* stats) { | |
45 ClearFrameStats(stats); // The histogram needs to be zeroed out. | |
46 if (frame.IsZeroSize()) { | |
47 return; | |
48 } | |
49 | |
50 int width = frame.width(); | |
51 int height = frame.height(); | |
52 stats->sub_sampling_factor = GetSubSamplingFactor(width, height); | |
53 | |
54 const uint8_t* buffer = frame.buffer(kYPlane); | |
55 // Compute histogram and sum of frame | |
56 for (int i = 0; i < height; i += (1 << stats->sub_sampling_factor)) { | |
57 int k = i * width; | |
58 for (int j = 0; j < width; j += (1 << stats->sub_sampling_factor)) { | |
59 stats->hist[buffer[k + j]]++; | |
60 stats->sum += buffer[k + j]; | |
61 } | |
62 } | |
63 | |
64 stats->num_pixels = (width * height) / ((1 << stats->sub_sampling_factor) * | |
65 (1 << stats->sub_sampling_factor)); | |
66 assert(stats->num_pixels > 0); | |
67 | |
68 // Compute mean value of frame | |
69 stats->mean = stats->sum / stats->num_pixels; | |
70 } | |
71 | |
72 bool VideoProcessing::ValidFrameStats(const FrameStats& stats) { | |
73 if (stats.num_pixels == 0) { | |
74 LOG(LS_WARNING) << "Invalid frame stats."; | |
75 return false; | |
76 } | |
77 return true; | |
78 } | |
79 | |
80 void VideoProcessing::ClearFrameStats(FrameStats* stats) { | |
81 stats->mean = 0; | |
82 stats->sum = 0; | |
83 stats->num_pixels = 0; | |
84 stats->sub_sampling_factor = 0; | |
85 memset(stats->hist, 0, sizeof(stats->hist)); | |
86 } | |
87 | |
88 void VideoProcessing::Brighten(int delta, VideoFrame* frame) { | |
89 RTC_DCHECK(!frame->IsZeroSize()); | |
90 RTC_DCHECK(frame->width() > 0); | |
91 RTC_DCHECK(frame->height() > 0); | |
92 | |
93 int num_pixels = frame->width() * frame->height(); | |
94 | |
95 int look_up[256]; | |
96 for (int i = 0; i < 256; i++) { | |
97 int val = i + delta; | |
98 look_up[i] = ((((val < 0) ? 0 : val) > 255) ? 255 : val); | |
99 } | |
100 | |
101 uint8_t* temp_ptr = frame->buffer(kYPlane); | |
102 for (int i = 0; i < num_pixels; i++) { | |
103 *temp_ptr = static_cast<uint8_t>(look_up[*temp_ptr]); | |
104 temp_ptr++; | |
105 } | |
106 } | |
107 | |
108 int32_t VideoProcessingImpl::Deflickering(VideoFrame* frame, | |
109 FrameStats* stats) { | |
110 rtc::CritScope mutex(&mutex_); | |
111 return deflickering_.ProcessFrame(frame, stats); | |
112 } | |
113 | |
114 int32_t VideoProcessingImpl::BrightnessDetection(const VideoFrame& frame, | |
115 const FrameStats& stats) { | |
116 rtc::CritScope mutex(&mutex_); | |
117 return brightness_detection_.ProcessFrame(frame, stats); | |
118 } | |
119 | |
120 void VideoProcessingImpl::EnableTemporalDecimation(bool enable) { | 28 void VideoProcessingImpl::EnableTemporalDecimation(bool enable) { |
121 rtc::CritScope mutex(&mutex_); | 29 rtc::CritScope mutex(&mutex_); |
122 frame_pre_processor_.EnableTemporalDecimation(enable); | 30 frame_pre_processor_.EnableTemporalDecimation(enable); |
123 } | 31 } |
124 | 32 |
125 void VideoProcessingImpl::SetInputFrameResampleMode( | 33 void VideoProcessingImpl::SetInputFrameResampleMode( |
126 VideoFrameResampling resampling_mode) { | 34 VideoFrameResampling resampling_mode) { |
127 rtc::CritScope cs(&mutex_); | 35 rtc::CritScope cs(&mutex_); |
128 frame_pre_processor_.SetInputFrameResampleMode(resampling_mode); | 36 frame_pre_processor_.SetInputFrameResampleMode(resampling_mode); |
129 } | 37 } |
(...skipping 18 matching lines...) Expand all Loading... |
148 uint32_t VideoProcessingImpl::GetDecimatedWidth() const { | 56 uint32_t VideoProcessingImpl::GetDecimatedWidth() const { |
149 rtc::CritScope cs(&mutex_); | 57 rtc::CritScope cs(&mutex_); |
150 return frame_pre_processor_.GetDecimatedWidth(); | 58 return frame_pre_processor_.GetDecimatedWidth(); |
151 } | 59 } |
152 | 60 |
153 uint32_t VideoProcessingImpl::GetDecimatedHeight() const { | 61 uint32_t VideoProcessingImpl::GetDecimatedHeight() const { |
154 rtc::CritScope cs(&mutex_); | 62 rtc::CritScope cs(&mutex_); |
155 return frame_pre_processor_.GetDecimatedHeight(); | 63 return frame_pre_processor_.GetDecimatedHeight(); |
156 } | 64 } |
157 | 65 |
158 void VideoProcessingImpl::EnableDenosing(bool enable) { | 66 void VideoProcessingImpl::EnableDenoising(bool enable) { |
159 rtc::CritScope cs(&mutex_); | 67 rtc::CritScope cs(&mutex_); |
160 frame_pre_processor_.EnableDenosing(enable); | 68 frame_pre_processor_.EnableDenoising(enable); |
161 } | 69 } |
162 | 70 |
163 const VideoFrame* VideoProcessingImpl::PreprocessFrame( | 71 const VideoFrame* VideoProcessingImpl::PreprocessFrame( |
164 const VideoFrame& frame) { | 72 const VideoFrame& frame) { |
165 rtc::CritScope mutex(&mutex_); | 73 rtc::CritScope mutex(&mutex_); |
166 return frame_pre_processor_.PreprocessFrame(frame); | 74 return frame_pre_processor_.PreprocessFrame(frame); |
167 } | 75 } |
168 | 76 |
169 VideoContentMetrics* VideoProcessingImpl::GetContentMetrics() const { | 77 VideoContentMetrics* VideoProcessingImpl::GetContentMetrics() const { |
170 rtc::CritScope mutex(&mutex_); | 78 rtc::CritScope mutex(&mutex_); |
171 return frame_pre_processor_.GetContentMetrics(); | 79 return frame_pre_processor_.GetContentMetrics(); |
172 } | 80 } |
173 | 81 |
174 void VideoProcessingImpl::EnableContentAnalysis(bool enable) { | 82 void VideoProcessingImpl::EnableContentAnalysis(bool enable) { |
175 rtc::CritScope mutex(&mutex_); | 83 rtc::CritScope mutex(&mutex_); |
176 frame_pre_processor_.EnableContentAnalysis(enable); | 84 frame_pre_processor_.EnableContentAnalysis(enable); |
177 } | 85 } |
178 | 86 |
179 } // namespace webrtc | 87 } // namespace webrtc |
OLD | NEW |