1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 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 11 12 #include "webrtc/modules/video_processing/main/source/video_processing_impl.h" 13 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 14 #include "webrtc/system_wrappers/interface/logging.h" 15 16 #include <assert.h> 17 18 namespace webrtc { 19 20 namespace { 21 void SetSubSampling(VideoProcessingModule::FrameStats* stats, 22 const int32_t width, 23 const int32_t height) { 24 if (width * height >= 640 * 480) { 25 stats->subSamplWidth = 3; 26 stats->subSamplHeight = 3; 27 } else if (width * height >= 352 * 288) { 28 stats->subSamplWidth = 2; 29 stats->subSamplHeight = 2; 30 } else if (width * height >= 176 * 144) { 31 stats->subSamplWidth = 1; 32 stats->subSamplHeight = 1; 33 } else { 34 stats->subSamplWidth = 0; 35 stats->subSamplHeight = 0; 36 } 37 } 38 } // namespace 39 40 VideoProcessingModule* VideoProcessingModule::Create(const int32_t id) { 41 return new VideoProcessingModuleImpl(id); 42 } 43 44 void VideoProcessingModule::Destroy(VideoProcessingModule* module) { 45 if (module) 46 delete static_cast<VideoProcessingModuleImpl*>(module); 47 } 48 49 int32_t VideoProcessingModuleImpl::ChangeUniqueId(const int32_t id) { 50 CriticalSectionScoped mutex(&mutex_); 51 id_ = id; 52 brightness_detection_.ChangeUniqueId(id); 53 deflickering_.ChangeUniqueId(id); 54 frame_pre_processor_.ChangeUniqueId(id); 55 return VPM_OK; 56 } 57 58 int32_t VideoProcessingModuleImpl::Id() const { 59 CriticalSectionScoped mutex(&mutex_); 60 return id_; 61 } 62 63 VideoProcessingModuleImpl::VideoProcessingModuleImpl(const int32_t id) 64 : id_(id), 65 mutex_(*CriticalSectionWrapper::CreateCriticalSection()) { 66 brightness_detection_.ChangeUniqueId(id); 67 deflickering_.ChangeUniqueId(id); 68 frame_pre_processor_.ChangeUniqueId(id); 69 } 70 71 VideoProcessingModuleImpl::~VideoProcessingModuleImpl() { 72 delete &mutex_; 73 } 74 75 void VideoProcessingModuleImpl::Reset() { 76 CriticalSectionScoped mutex(&mutex_); 77 deflickering_.Reset(); 78 brightness_detection_.Reset(); 79 frame_pre_processor_.Reset(); 80 } 81 82 int32_t VideoProcessingModule::GetFrameStats(FrameStats* stats, 83 const I420VideoFrame& frame) { 84 if (frame.IsZeroSize()) { 85 LOG(LS_ERROR) << "Zero size frame."; 86 return VPM_PARAMETER_ERROR; 87 } 88 89 int width = frame.width(); 90 int height = frame.height(); 91 92 ClearFrameStats(stats); // The histogram needs to be zeroed out. 93 SetSubSampling(stats, width, height); 94 95 const uint8_t* buffer = frame.buffer(kYPlane); 96 // Compute histogram and sum of frame 97 for (int i = 0; i < height; i += (1 << stats->subSamplHeight)) { 98 int k = i * width; 99 for (int j = 0; j < width; j += (1 << stats->subSamplWidth)) { 100 stats->hist[buffer[k + j]]++; 101 stats->sum += buffer[k + j]; 102 } 103 } 104 105 stats->num_pixels = (width * height) / ((1 << stats->subSamplWidth) * 106 (1 << stats->subSamplHeight)); 107 assert(stats->num_pixels > 0); 108 109 // Compute mean value of frame 110 stats->mean = stats->sum / stats->num_pixels; 111 112 return VPM_OK; 113 } 114 115 bool VideoProcessingModule::ValidFrameStats(const FrameStats& stats) { 116 if (stats.num_pixels == 0) { 117 LOG(LS_WARNING) << "Invalid frame stats."; 118 return false; 119 } 120 return true; 121 } 122 123 void VideoProcessingModule::ClearFrameStats(FrameStats* stats) { 124 stats->mean = 0; 125 stats->sum = 0; 126 stats->num_pixels = 0; 127 stats->subSamplWidth = 0; 128 stats->subSamplHeight = 0; 129 memset(stats->hist, 0, sizeof(stats->hist)); 130 } 131 132 int32_t VideoProcessingModule::ColorEnhancement(I420VideoFrame* frame) { 133 return VideoProcessing::ColorEnhancement(frame); 134 } 135 136 int32_t VideoProcessingModule::Brighten(I420VideoFrame* frame, int delta) { 137 return VideoProcessing::Brighten(frame, delta); 138 } 139 140 int32_t VideoProcessingModuleImpl::Deflickering(I420VideoFrame* frame, 141 FrameStats* stats) { 142 CriticalSectionScoped mutex(&mutex_); 143 return deflickering_.ProcessFrame(frame, stats); 144 } 145 146 int32_t VideoProcessingModuleImpl::BrightnessDetection( 147 const I420VideoFrame& frame, 148 const FrameStats& stats) { 149 CriticalSectionScoped mutex(&mutex_); 150 return brightness_detection_.ProcessFrame(frame, stats); 151 } 152 153 154 void VideoProcessingModuleImpl::EnableTemporalDecimation(bool enable) { 155 CriticalSectionScoped mutex(&mutex_); 156 frame_pre_processor_.EnableTemporalDecimation(enable); 157 } 158 159 160 void VideoProcessingModuleImpl::SetInputFrameResampleMode(VideoFrameResampling 161 resampling_mode) { 162 CriticalSectionScoped cs(&mutex_); 163 frame_pre_processor_.SetInputFrameResampleMode(resampling_mode); 164 } 165 166 int32_t VideoProcessingModuleImpl::SetTargetResolution(uint32_t width, 167 uint32_t height, 168 uint32_t frame_rate) { 169 CriticalSectionScoped cs(&mutex_); 170 return frame_pre_processor_.SetTargetResolution(width, height, frame_rate); 171 } 172 173 uint32_t VideoProcessingModuleImpl::Decimatedframe_rate() { 174 CriticalSectionScoped cs(&mutex_); 175 return frame_pre_processor_.Decimatedframe_rate(); 176 } 177 178 uint32_t VideoProcessingModuleImpl::DecimatedWidth() const { 179 CriticalSectionScoped cs(&mutex_); 180 return frame_pre_processor_.DecimatedWidth(); 181 } 182 183 uint32_t VideoProcessingModuleImpl::DecimatedHeight() const { 184 CriticalSectionScoped cs(&mutex_); 185 return frame_pre_processor_.DecimatedHeight(); 186 } 187 188 int32_t VideoProcessingModuleImpl::PreprocessFrame( 189 const I420VideoFrame& frame, 190 I420VideoFrame **processed_frame) { 191 CriticalSectionScoped mutex(&mutex_); 192 return frame_pre_processor_.PreprocessFrame(frame, processed_frame); 193 } 194 195 VideoContentMetrics* VideoProcessingModuleImpl::ContentMetrics() const { 196 CriticalSectionScoped mutex(&mutex_); 197 return frame_pre_processor_.ContentMetrics(); 198 } 199 200 void VideoProcessingModuleImpl::EnableContentAnalysis(bool enable) { 201 CriticalSectionScoped mutex(&mutex_); 202 frame_pre_processor_.EnableContentAnalysis(enable); 203 } 204 205 } // namespace webrtc 206