OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 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/util/noise_estimation.h" | 11 #include "webrtc/modules/video_processing/util/noise_estimation.h" |
12 | 12 |
13 namespace webrtc { | 13 namespace webrtc { |
14 | 14 |
15 void NoiseEstimation::Init(int width, int height, CpuType cpu_type) { | 15 void NoiseEstimation::Init(int width, int height, CpuType cpu_type) { |
16 int mb_cols = width >> 4; | 16 int mb_cols = width >> 4; |
17 int mb_rows = height >> 4; | 17 int mb_rows = height >> 4; |
18 consec_low_var_.reset(new uint32_t[mb_cols * mb_rows]()); | 18 consec_low_var_.reset(new uint32_t[mb_cols * mb_rows]()); |
19 width_ = width; | 19 width_ = width; |
20 height_ = height; | 20 height_ = height; |
21 mb_cols_ = width_ >> 4; | 21 mb_cols_ = width_ >> 4; |
22 mb_rows_ = height_ >> 4; | 22 mb_rows_ = height_ >> 4; |
23 cpu_type_ = cpu_type; | 23 cpu_type_ = cpu_type; |
24 } | 24 } |
25 | 25 |
26 void NoiseEstimation::GetNoise(int mb_index, uint32_t var, uint32_t luma) { | 26 void NoiseEstimation::GetNoise(int mb_index, uint32_t var, uint32_t luma) { |
27 consec_low_var_[mb_index]++; | 27 consec_low_var_[mb_index]++; |
28 num_static_block_++; | 28 num_static_block_++; |
29 if (consec_low_var_[mb_index] >= kConsecLowVarFrame && | 29 if (consec_low_var_[mb_index] >= kConsecLowVarFrame && |
30 (luma >> 8) < kAverageLumaMax && (luma >> 8) > kAverageLumaMin) { | 30 (luma >> 6) < kAverageLumaMax && (luma >> 6) > kAverageLumaMin) { |
31 // Normalized var by the average luma value, this gives more weight to | 31 // Normalized var by the average luma value, this gives more weight to |
32 // darker blocks. | 32 // darker blocks. |
33 int nor_var = var / (luma >> 12); | 33 int nor_var = var / (luma >> 10); |
34 noise_var_ += | 34 noise_var_ += |
35 nor_var > kBlockSelectionVarMax ? kBlockSelectionVarMax : nor_var; | 35 nor_var > kBlockSelectionVarMax ? kBlockSelectionVarMax : nor_var; |
36 num_noisy_block_++; | 36 num_noisy_block_++; |
37 } | 37 } |
38 } | 38 } |
39 | 39 |
40 void NoiseEstimation::ResetConsecLowVar(int mb_index) { | 40 void NoiseEstimation::ResetConsecLowVar(int mb_index) { |
41 consec_low_var_[mb_index] = 0; | 41 consec_low_var_[mb_index] = 0; |
42 } | 42 } |
43 | 43 |
44 void NoiseEstimation::UpdateNoiseLevel() { | 44 void NoiseEstimation::UpdateNoiseLevel() { |
45 // TODO(jackychen): Tune a threshold for numb_noisy_block > T to make the | 45 // TODO(jackychen): Tune a threshold for numb_noisy_block > T to make the |
46 // condition more reasonable. | 46 // condition more reasonable. |
47 // No enough samples implies the motion of the camera or too many moving | 47 // No enough samples implies the motion of the camera or too many moving |
48 // objects in the frame. | 48 // objects in the frame. |
49 if (num_static_block_ < (0.65 * mb_cols_ * mb_rows_) || !num_noisy_block_) { | 49 if (num_static_block_ < |
| 50 (0.65 * mb_cols_ * mb_rows_ / NOISE_SUBSAMPLE_INTERVAL) || |
| 51 !num_noisy_block_) { |
| 52 #if DISPLAY |
| 53 printf("Not enough samples. %d \n", num_static_block_); |
| 54 #endif |
50 noise_var_ = 0; | 55 noise_var_ = 0; |
51 noise_var_accum_ = 0; | 56 noise_var_accum_ = 0; |
| 57 num_noisy_block_ = 0; |
52 num_static_block_ = 0; | 58 num_static_block_ = 0; |
53 num_noisy_block_ = 0; | |
54 #if DISPLAY | |
55 printf("Not enough samples.\n"); | |
56 #endif | |
57 return; | 59 return; |
58 } else { | 60 } else { |
| 61 #if DISPLAY |
| 62 printf("%d %d fraction = %.3f\n", num_static_block_, |
| 63 mb_cols_ * mb_rows_ / NOISE_SUBSAMPLE_INTERVAL, |
| 64 percent_static_block_); |
| 65 #endif |
59 // Normalized by the number of noisy blocks. | 66 // Normalized by the number of noisy blocks. |
60 noise_var_ /= num_noisy_block_; | 67 noise_var_ /= num_noisy_block_; |
61 // Get the percentage of static blocks. | 68 // Get the percentage of static blocks. |
62 percent_static_block_ = | 69 percent_static_block_ = static_cast<double>(num_static_block_) / |
63 static_cast<double>(num_static_block_) / (mb_cols_ * mb_rows_); | 70 (mb_cols_ * mb_rows_ / NOISE_SUBSAMPLE_INTERVAL); |
64 #if DISPLAY | |
65 printf("%d %d fraction = %.3f\n", num_static_block_, mb_cols_ * mb_rows_, | |
66 percent_static_block_); | |
67 #endif | |
68 num_noisy_block_ = 0; | 71 num_noisy_block_ = 0; |
69 num_static_block_ = 0; | 72 num_static_block_ = 0; |
70 } | 73 } |
71 // For the first frame just update the value with current noise_var_, | 74 // For the first frame just update the value with current noise_var_, |
72 // otherwise, use the averaging window. | 75 // otherwise, use the averaging window. |
73 if (noise_var_accum_ == 0) { | 76 if (noise_var_accum_ == 0) { |
74 noise_var_accum_ = noise_var_; | 77 noise_var_accum_ = noise_var_; |
75 } else { | 78 } else { |
76 noise_var_accum_ = (noise_var_accum_ * 15 + noise_var_) / 16; | 79 noise_var_accum_ = (noise_var_accum_ * 15 + noise_var_) / 16; |
77 } | 80 } |
78 // Reset noise_var_ for the next frame. | |
79 noise_var_ = 0; | |
80 #if DISPLAY | 81 #if DISPLAY |
81 printf("noise_var_accum_ = %.1f, noise_var_ = %d.\n", noise_var_accum_, | 82 printf("noise_var_accum_ = %.1f, noise_var_ = %d.\n", noise_var_accum_, |
82 noise_var_); | 83 noise_var_); |
83 #endif | 84 #endif |
| 85 // Reset noise_var_ for the next frame. |
| 86 noise_var_ = 0; |
84 } | 87 } |
85 | 88 |
86 uint8_t NoiseEstimation::GetNoiseLevel() { | 89 uint8_t NoiseEstimation::GetNoiseLevel() { |
87 int noise_thr = cpu_type_ ? kNoiseThreshold : kNoiseThresholdNeon; | 90 int noise_thr = cpu_type_ ? kNoiseThreshold : kNoiseThresholdNeon; |
88 UpdateNoiseLevel(); | 91 UpdateNoiseLevel(); |
89 if (noise_var_accum_ > noise_thr) { | 92 if (noise_var_accum_ > noise_thr) { |
90 return 1; | 93 return 1; |
91 } | 94 } |
92 return 0; | 95 return 0; |
93 } | 96 } |
94 | 97 |
95 } // namespace webrtc | 98 } // namespace webrtc |
OLD | NEW |