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