blob: f1bd82255bbc039d6dfa79332b8c0ecb9dd889ae [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
19
niklase@google.com470e71d2011-07-07 08:21:25 +000020namespace webrtc {
21
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000022namespace {
mflodmana8565422015-12-07 01:09:52 -080023
24int GetSubSamplingFactor(int width, int height) {
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000025 if (width * height >= 640 * 480) {
mflodmana8565422015-12-07 01:09:52 -080026 return 3;
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000027 } else if (width * height >= 352 * 288) {
mflodmana8565422015-12-07 01:09:52 -080028 return 2;
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000029 } else if (width * height >= 176 * 144) {
mflodmana8565422015-12-07 01:09:52 -080030 return 1;
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000031 } else {
mflodmana8565422015-12-07 01:09:52 -080032 return 0;
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000033 }
niklase@google.com470e71d2011-07-07 08:21:25 +000034}
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +000035} // namespace
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000036
mflodmana8565422015-12-07 01:09:52 -080037VideoProcessing* VideoProcessing::Create() {
38 return new VideoProcessingImpl();
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000039}
40
mflodmana8565422015-12-07 01:09:52 -080041VideoProcessingImpl::VideoProcessingImpl() {}
42VideoProcessingImpl::~VideoProcessingImpl() {}
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000043
mflodmana8565422015-12-07 01:09:52 -080044void VideoProcessing::GetFrameStats(const VideoFrame& frame,
45 FrameStats* stats) {
46 ClearFrameStats(stats); // The histogram needs to be zeroed out.
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000047 if (frame.IsZeroSize()) {
mflodmana8565422015-12-07 01:09:52 -080048 return;
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000049 }
50
51 int width = frame.width();
52 int height = frame.height();
mflodmana8565422015-12-07 01:09:52 -080053 stats->sub_sampling_factor = GetSubSamplingFactor(width, height);
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000054
55 const uint8_t* buffer = frame.buffer(kYPlane);
56 // Compute histogram and sum of frame
mflodmana8565422015-12-07 01:09:52 -080057 for (int i = 0; i < height; i += (1 << stats->sub_sampling_factor)) {
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000058 int k = i * width;
mflodmana8565422015-12-07 01:09:52 -080059 for (int j = 0; j < width; j += (1 << stats->sub_sampling_factor)) {
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000060 stats->hist[buffer[k + j]]++;
61 stats->sum += buffer[k + j];
62 }
63 }
64
mflodmana8565422015-12-07 01:09:52 -080065 stats->num_pixels = (width * height) /
66 ((1 << stats->sub_sampling_factor) * (1 << stats->sub_sampling_factor));
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000067 assert(stats->num_pixels > 0);
68
69 // Compute mean value of frame
70 stats->mean = stats->sum / stats->num_pixels;
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000071}
72
mflodmana8565422015-12-07 01:09:52 -080073bool VideoProcessing::ValidFrameStats(const FrameStats& stats) {
asapersson@webrtc.org2a770822014-04-10 11:30:49 +000074 if (stats.num_pixels == 0) {
75 LOG(LS_WARNING) << "Invalid frame stats.";
76 return false;
77 }
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000078 return true;
79}
80
mflodmana8565422015-12-07 01:09:52 -080081void VideoProcessing::ClearFrameStats(FrameStats* stats) {
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000082 stats->mean = 0;
83 stats->sum = 0;
84 stats->num_pixels = 0;
mflodmana8565422015-12-07 01:09:52 -080085 stats->sub_sampling_factor = 0;
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +000086 memset(stats->hist, 0, sizeof(stats->hist));
87}
88
mflodmana8565422015-12-07 01:09:52 -080089void VideoProcessing::Brighten(int delta, VideoFrame* frame) {
90 RTC_DCHECK(!frame->IsZeroSize());
91 RTC_DCHECK(frame->width() > 0);
92 RTC_DCHECK(frame->height() > 0);
93
94 int num_pixels = frame->width() * frame->height();
95
96 int look_up[256];
97 for (int i = 0; i < 256; i++) {
98 int val = i + delta;
99 look_up[i] = ((((val < 0) ? 0 : val) > 255) ? 255 : val);
100 }
101
102 uint8_t* temp_ptr = frame->buffer(kYPlane);
103 for (int i = 0; i < num_pixels; i++) {
104 *temp_ptr = static_cast<uint8_t>(look_up[*temp_ptr]);
105 temp_ptr++;
106 }
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000107}
108
mflodmana8565422015-12-07 01:09:52 -0800109int32_t VideoProcessingImpl::Deflickering(VideoFrame* frame,
110 FrameStats* stats) {
Peter Boströmf4aa4c22015-09-18 12:24:25 +0200111 rtc::CritScope mutex(&mutex_);
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000112 return deflickering_.ProcessFrame(frame, stats);
113}
114
mflodmana8565422015-12-07 01:09:52 -0800115int32_t VideoProcessingImpl::BrightnessDetection(
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700116 const VideoFrame& frame,
117 const FrameStats& stats) {
Peter Boströmf4aa4c22015-09-18 12:24:25 +0200118 rtc::CritScope mutex(&mutex_);
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000119 return brightness_detection_.ProcessFrame(frame, stats);
120}
121
122
mflodmana8565422015-12-07 01:09:52 -0800123void VideoProcessingImpl::EnableTemporalDecimation(bool enable) {
Peter Boströmf4aa4c22015-09-18 12:24:25 +0200124 rtc::CritScope mutex(&mutex_);
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000125 frame_pre_processor_.EnableTemporalDecimation(enable);
126}
127
128
mflodmana8565422015-12-07 01:09:52 -0800129void VideoProcessingImpl::SetInputFrameResampleMode(VideoFrameResampling
130 resampling_mode) {
Peter Boströmf4aa4c22015-09-18 12:24:25 +0200131 rtc::CritScope cs(&mutex_);
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000132 frame_pre_processor_.SetInputFrameResampleMode(resampling_mode);
133}
134
mflodmana8565422015-12-07 01:09:52 -0800135int32_t VideoProcessingImpl::SetTargetResolution(uint32_t width,
136 uint32_t height,
137 uint32_t frame_rate) {
Peter Boströmf4aa4c22015-09-18 12:24:25 +0200138 rtc::CritScope cs(&mutex_);
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000139 return frame_pre_processor_.SetTargetResolution(width, height, frame_rate);
140}
141
mflodmana8565422015-12-07 01:09:52 -0800142void VideoProcessingImpl::SetTargetFramerate(int frame_rate) {
Peter Boströmf4aa4c22015-09-18 12:24:25 +0200143 rtc::CritScope cs(&mutex_);
jackychen6e2ce6e2015-07-13 16:26:33 -0700144 frame_pre_processor_.SetTargetFramerate(frame_rate);
145}
146
mflodmana8565422015-12-07 01:09:52 -0800147uint32_t VideoProcessingImpl::GetDecimatedFrameRate() {
Peter Boströmf4aa4c22015-09-18 12:24:25 +0200148 rtc::CritScope cs(&mutex_);
mflodmana8565422015-12-07 01:09:52 -0800149 return frame_pre_processor_.GetDecimatedFrameRate();
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000150}
151
mflodmana8565422015-12-07 01:09:52 -0800152uint32_t VideoProcessingImpl::GetDecimatedWidth() const {
Peter Boströmf4aa4c22015-09-18 12:24:25 +0200153 rtc::CritScope cs(&mutex_);
mflodmana8565422015-12-07 01:09:52 -0800154 return frame_pre_processor_.GetDecimatedWidth();
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000155}
156
mflodmana8565422015-12-07 01:09:52 -0800157uint32_t VideoProcessingImpl::GetDecimatedHeight() const {
Peter Boströmf4aa4c22015-09-18 12:24:25 +0200158 rtc::CritScope cs(&mutex_);
mflodmana8565422015-12-07 01:09:52 -0800159 return frame_pre_processor_.GetDecimatedHeight();
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000160}
161
mflodmana8565422015-12-07 01:09:52 -0800162void VideoProcessingImpl::EnableDenosing(bool enable) {
163 rtc::CritScope cs(&mutex_);
164 frame_pre_processor_.EnableDenosing(enable);
165}
166
167const VideoFrame* VideoProcessingImpl::PreprocessFrame(
168 const VideoFrame& frame) {
Peter Boströmf4aa4c22015-09-18 12:24:25 +0200169 rtc::CritScope mutex(&mutex_);
mflodmana8565422015-12-07 01:09:52 -0800170 return frame_pre_processor_.PreprocessFrame(frame);
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000171}
172
mflodmana8565422015-12-07 01:09:52 -0800173VideoContentMetrics* VideoProcessingImpl::GetContentMetrics() const {
Peter Boströmf4aa4c22015-09-18 12:24:25 +0200174 rtc::CritScope mutex(&mutex_);
mflodmana8565422015-12-07 01:09:52 -0800175 return frame_pre_processor_.GetContentMetrics();
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000176}
177
mflodmana8565422015-12-07 01:09:52 -0800178void VideoProcessingImpl::EnableContentAnalysis(bool enable) {
Peter Boströmf4aa4c22015-09-18 12:24:25 +0200179 rtc::CritScope mutex(&mutex_);
mikhal@webrtc.orgb43d8072013-10-03 16:42:41 +0000180 frame_pre_processor_.EnableContentAnalysis(enable);
181}
182
183} // namespace webrtc