2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
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.
11 #include "webrtc/modules/video_processing/main/interface/video_processing.h"
12 #include "webrtc/modules/video_processing/main/source/brightness_detection.h"
18 VPMBrightnessDetection::VPMBrightnessDetection() :
23 VPMBrightnessDetection::~VPMBrightnessDetection() {}
25 int32_t VPMBrightnessDetection::ChangeUniqueId(const int32_t id) {
30 void VPMBrightnessDetection::Reset() {
31 frame_cnt_bright_ = 0;
35 int32_t VPMBrightnessDetection::ProcessFrame(
36 const I420VideoFrame& frame,
37 const VideoProcessingModule::FrameStats& stats) {
38 if (frame.IsZeroSize()) {
39 return VPM_PARAMETER_ERROR;
41 int width = frame.width();
42 int height = frame.height();
44 if (!VideoProcessingModule::ValidFrameStats(stats)) {
45 return VPM_PARAMETER_ERROR;
48 const uint8_t frame_cnt_alarm = 2;
50 // Get proportion in lowest bins.
53 for (uint32_t i = 0; i < low_th; i++) {
54 prop_low += stats.hist[i];
56 prop_low /= stats.num_pixels;
58 // Get proportion in highest bins.
59 unsigned char high_th = 230;
61 for (uint32_t i = high_th; i < 256; i++) {
62 prop_high += stats.hist[i];
64 prop_high /= stats.num_pixels;
66 if (prop_high < 0.4) {
67 if (stats.mean < 90 || stats.mean > 170) {
68 // Standard deviation of Y
69 const uint8_t* buffer = frame.buffer(kYPlane);
71 for (int h = 0; h < height; h += (1 << stats.subSamplHeight)) {
73 for (int w = 0; w < width; w += (1 << stats.subSamplWidth)) {
74 std_y += (buffer[w + row] - stats.mean) * (buffer[w + row] -
78 std_y = sqrt(std_y / stats.num_pixels);
82 uint32_t median_y = 140;
84 uint32_t perc95 = 255;
85 float pos_perc05 = stats.num_pixels * 0.05f;
86 float pos_median = stats.num_pixels * 0.5f;
87 float posPerc95 = stats.num_pixels * 0.95f;
88 for (uint32_t i = 0; i < 256; i++) {
90 if (sum < pos_perc05) perc05 = i; // 5th perc.
91 if (sum < pos_median) median_y = i; // 50th perc.
93 perc95 = i; // 95th perc.
98 // Check if image is too dark
99 if ((std_y < 55) && (perc05 < 50)) {
100 if (median_y < 60 || stats.mean < 80 || perc95 < 130 ||
110 // Check if image is too bright
111 if ((std_y < 52) && (perc95 > 200) && (median_y > 160)) {
112 if (median_y > 185 || stats.mean > 185 || perc05 > 140 ||
116 frame_cnt_bright_ = 0;
119 frame_cnt_bright_ = 0;
123 frame_cnt_bright_ = 0;
130 if (frame_cnt_dark_ > frame_cnt_alarm) {
131 return VideoProcessingModule::kDarkWarning;
132 } else if (frame_cnt_bright_ > frame_cnt_alarm) {
133 return VideoProcessingModule::kBrightWarning;
135 return VideoProcessingModule::kNoWarning;
139 } // namespace webrtc