blob: cb52c672e03b00cfc104ce023229d72e13e2735b [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
xians@webrtc.org9a798d32012-02-20 09:00:35 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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 */
mflodmana8565422015-12-07 01:09:52 -080010
Henrik Kjellander0f59a882015-11-18 22:31:24 +010011#include "webrtc/modules/video_processing/video_processing_impl.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
pbos@webrtc.org12dc1a32013-08-05 16:22:53 +000013#include <assert.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000014
mflodmana8565422015-12-07 01:09:52 -080015#include "webrtc/base/checks.h"
16#include "webrtc/base/logging.h"
17#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
18
niklase@google.com470e71d2011-07-07 08:21:25 +000019namespace webrtc {
20
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000021namespace {
mflodmana8565422015-12-07 01:09:52 -080022
23int GetSubSamplingFactor(int width, int height) {
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000024 if (width * height >= 640 * 480) {
mflodmana8565422015-12-07 01:09:52 -080025 return 3;
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000026 } else if (width * height >= 352 * 288) {
mflodmana8565422015-12-07 01:09:52 -080027 return 2;
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000028 } else if (width * height >= 176 * 144) {
mflodmana8565422015-12-07 01:09:52 -080029 return 1;
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000030 } else {
mflodmana8565422015-12-07 01:09:52 -080031 return 0;
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000032 }
niklase@google.com470e71d2011-07-07 08:21:25 +000033}
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +000034} // namespace
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000035
mflodmana8565422015-12-07 01:09:52 -080036VideoProcessing* VideoProcessing::Create() {
37 return new VideoProcessingImpl();
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000038}
39
mflodmana8565422015-12-07 01:09:52 -080040VideoProcessingImpl::VideoProcessingImpl() {}
41VideoProcessingImpl::~VideoProcessingImpl() {}
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000042
mflodmana8565422015-12-07 01:09:52 -080043void VideoProcessing::GetFrameStats(const VideoFrame& frame,
44 FrameStats* stats) {
45 ClearFrameStats(stats); // The histogram needs to be zeroed out.
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000046 if (frame.IsZeroSize()) {
mflodmana8565422015-12-07 01:09:52 -080047 return;
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000048 }
49
50 int width = frame.width();
51 int height = frame.height();
mflodmana8565422015-12-07 01:09:52 -080052 stats->sub_sampling_factor = GetSubSamplingFactor(width, height);
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000053
54 const uint8_t* buffer = frame.buffer(kYPlane);
55 // Compute histogram and sum of frame
mflodmana8565422015-12-07 01:09:52 -080056 for (int i = 0; i < height; i += (1 << stats->sub_sampling_factor)) {
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000057 int k = i * width;
mflodmana8565422015-12-07 01:09:52 -080058 for (int j = 0; j < width; j += (1 << stats->sub_sampling_factor)) {
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000059 stats->hist[buffer[k + j]]++;
60 stats->sum += buffer[k + j];
61 }
62 }
63
mflodman99ab9442015-12-07 22:54:50 -080064 stats->num_pixels = (width * height) / ((1 << stats->sub_sampling_factor) *
65 (1 << stats->sub_sampling_factor));
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000066 assert(stats->num_pixels > 0);
67
68 // Compute mean value of frame
69 stats->mean = stats->sum / stats->num_pixels;
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000070}
71
mflodmana8565422015-12-07 01:09:52 -080072bool VideoProcessing::ValidFrameStats(const FrameStats& stats) {
asapersson@webrtc.org2a770822014-04-10 11:30:49 +000073 if (stats.num_pixels == 0) {
74 LOG(LS_WARNING) << "Invalid frame stats.";
75 return false;
76 }
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000077 return true;
78}
79
mflodmana8565422015-12-07 01:09:52 -080080void VideoProcessing::ClearFrameStats(FrameStats* stats) {
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000081 stats->mean = 0;
82 stats->sum = 0;
83 stats->num_pixels = 0;
mflodmana8565422015-12-07 01:09:52 -080084 stats->sub_sampling_factor = 0;
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000085 memset(stats->hist, 0, sizeof(stats->hist));
86}
87
mflodmana8565422015-12-07 01:09:52 -080088void 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 }
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000106}
107
mflodmana8565422015-12-07 01:09:52 -0800108int32_t VideoProcessingImpl::Deflickering(VideoFrame* frame,
109 FrameStats* stats) {
Peter Boströmf4aa4c22015-09-18 12:24:25 +0200110 rtc::CritScope mutex(&mutex_);
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000111 return deflickering_.ProcessFrame(frame, stats);
112}
113
mflodman99ab9442015-12-07 22:54:50 -0800114int32_t VideoProcessingImpl::BrightnessDetection(const VideoFrame& frame,
115 const FrameStats& stats) {
Peter Boströmf4aa4c22015-09-18 12:24:25 +0200116 rtc::CritScope mutex(&mutex_);
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000117 return brightness_detection_.ProcessFrame(frame, stats);
118}
119
mflodmana8565422015-12-07 01:09:52 -0800120void VideoProcessingImpl::EnableTemporalDecimation(bool enable) {
Peter Boströmf4aa4c22015-09-18 12:24:25 +0200121 rtc::CritScope mutex(&mutex_);
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000122 frame_pre_processor_.EnableTemporalDecimation(enable);
123}
124
mflodman99ab9442015-12-07 22:54:50 -0800125void VideoProcessingImpl::SetInputFrameResampleMode(
126 VideoFrameResampling resampling_mode) {
Peter Boströmf4aa4c22015-09-18 12:24:25 +0200127 rtc::CritScope cs(&mutex_);
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000128 frame_pre_processor_.SetInputFrameResampleMode(resampling_mode);
129}
130
mflodmana8565422015-12-07 01:09:52 -0800131int32_t VideoProcessingImpl::SetTargetResolution(uint32_t width,
132 uint32_t height,
133 uint32_t frame_rate) {
Peter Boströmf4aa4c22015-09-18 12:24:25 +0200134 rtc::CritScope cs(&mutex_);
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000135 return frame_pre_processor_.SetTargetResolution(width, height, frame_rate);
136}
137
mflodmana8565422015-12-07 01:09:52 -0800138uint32_t VideoProcessingImpl::GetDecimatedFrameRate() {
Peter Boströmf4aa4c22015-09-18 12:24:25 +0200139 rtc::CritScope cs(&mutex_);
mflodman99ab9442015-12-07 22:54:50 -0800140 return frame_pre_processor_.GetDecimatedFrameRate();
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000141}
142
mflodmana8565422015-12-07 01:09:52 -0800143uint32_t VideoProcessingImpl::GetDecimatedWidth() const {
Peter Boströmf4aa4c22015-09-18 12:24:25 +0200144 rtc::CritScope cs(&mutex_);
mflodmana8565422015-12-07 01:09:52 -0800145 return frame_pre_processor_.GetDecimatedWidth();
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000146}
147
mflodmana8565422015-12-07 01:09:52 -0800148uint32_t VideoProcessingImpl::GetDecimatedHeight() const {
Peter Boströmf4aa4c22015-09-18 12:24:25 +0200149 rtc::CritScope cs(&mutex_);
mflodmana8565422015-12-07 01:09:52 -0800150 return frame_pre_processor_.GetDecimatedHeight();
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000151}
152
mflodmana8565422015-12-07 01:09:52 -0800153void VideoProcessingImpl::EnableDenosing(bool enable) {
154 rtc::CritScope cs(&mutex_);
155 frame_pre_processor_.EnableDenosing(enable);
156}
157
158const VideoFrame* VideoProcessingImpl::PreprocessFrame(
159 const VideoFrame& frame) {
Peter Boströmf4aa4c22015-09-18 12:24:25 +0200160 rtc::CritScope mutex(&mutex_);
mflodmana8565422015-12-07 01:09:52 -0800161 return frame_pre_processor_.PreprocessFrame(frame);
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000162}
163
mflodmana8565422015-12-07 01:09:52 -0800164VideoContentMetrics* VideoProcessingImpl::GetContentMetrics() const {
Peter Boströmf4aa4c22015-09-18 12:24:25 +0200165 rtc::CritScope mutex(&mutex_);
mflodmana8565422015-12-07 01:09:52 -0800166 return frame_pre_processor_.GetContentMetrics();
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000167}
168
mflodmana8565422015-12-07 01:09:52 -0800169void VideoProcessingImpl::EnableContentAnalysis(bool enable) {
Peter Boströmf4aa4c22015-09-18 12:24:25 +0200170 rtc::CritScope mutex(&mutex_);
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000171 frame_pre_processor_.EnableContentAnalysis(enable);
172}
173
174} // namespace webrtc