Home | History | Annotate | Download | only in video_processing
      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 #include "webrtc/modules/video_processing/video_processing_impl.h"
     12 
     13 #include <assert.h>
     14 
     15 #include "webrtc/base/checks.h"
     16 #include "webrtc/base/logging.h"
     17 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
     18 
     19 namespace webrtc {
     20 
     21 namespace {
     22 
     23 int GetSubSamplingFactor(int width, int height) {
     24   if (width * height >= 640 * 480) {
     25     return 3;
     26   } else if (width * height >= 352 * 288) {
     27     return 2;
     28   } else if (width * height >= 176 * 144) {
     29     return 1;
     30   } else {
     31     return 0;
     32   }
     33 }
     34 }  // namespace
     35 
     36 VideoProcessing* VideoProcessing::Create() {
     37   return new VideoProcessingImpl();
     38 }
     39 
     40 VideoProcessingImpl::VideoProcessingImpl() {}
     41 VideoProcessingImpl::~VideoProcessingImpl() {}
     42 
     43 void VideoProcessing::GetFrameStats(const VideoFrame& frame,
     44                                     FrameStats* stats) {
     45   ClearFrameStats(stats);  // The histogram needs to be zeroed out.
     46   if (frame.IsZeroSize()) {
     47     return;
     48   }
     49 
     50   int width = frame.width();
     51   int height = frame.height();
     52   stats->sub_sampling_factor = GetSubSamplingFactor(width, height);
     53 
     54   const uint8_t* buffer = frame.buffer(kYPlane);
     55   // Compute histogram and sum of frame
     56   for (int i = 0; i < height; i += (1 << stats->sub_sampling_factor)) {
     57     int k = i * width;
     58     for (int j = 0; j < width; j += (1 << stats->sub_sampling_factor)) {
     59       stats->hist[buffer[k + j]]++;
     60       stats->sum += buffer[k + j];
     61     }
     62   }
     63 
     64   stats->num_pixels = (width * height) / ((1 << stats->sub_sampling_factor) *
     65                                           (1 << stats->sub_sampling_factor));
     66   assert(stats->num_pixels > 0);
     67 
     68   // Compute mean value of frame
     69   stats->mean = stats->sum / stats->num_pixels;
     70 }
     71 
     72 bool VideoProcessing::ValidFrameStats(const FrameStats& stats) {
     73   if (stats.num_pixels == 0) {
     74     LOG(LS_WARNING) << "Invalid frame stats.";
     75     return false;
     76   }
     77   return true;
     78 }
     79 
     80 void VideoProcessing::ClearFrameStats(FrameStats* stats) {
     81   stats->mean = 0;
     82   stats->sum = 0;
     83   stats->num_pixels = 0;
     84   stats->sub_sampling_factor = 0;
     85   memset(stats->hist, 0, sizeof(stats->hist));
     86 }
     87 
     88 void 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   }
    106 }
    107 
    108 int32_t VideoProcessingImpl::Deflickering(VideoFrame* frame,
    109                                           FrameStats* stats) {
    110   rtc::CritScope mutex(&mutex_);
    111   return deflickering_.ProcessFrame(frame, stats);
    112 }
    113 
    114 int32_t VideoProcessingImpl::BrightnessDetection(const VideoFrame& frame,
    115                                                  const FrameStats& stats) {
    116   rtc::CritScope mutex(&mutex_);
    117   return brightness_detection_.ProcessFrame(frame, stats);
    118 }
    119 
    120 void VideoProcessingImpl::EnableTemporalDecimation(bool enable) {
    121   rtc::CritScope mutex(&mutex_);
    122   frame_pre_processor_.EnableTemporalDecimation(enable);
    123 }
    124 
    125 void VideoProcessingImpl::SetInputFrameResampleMode(
    126     VideoFrameResampling resampling_mode) {
    127   rtc::CritScope cs(&mutex_);
    128   frame_pre_processor_.SetInputFrameResampleMode(resampling_mode);
    129 }
    130 
    131 int32_t VideoProcessingImpl::SetTargetResolution(uint32_t width,
    132                                                  uint32_t height,
    133                                                  uint32_t frame_rate) {
    134   rtc::CritScope cs(&mutex_);
    135   return frame_pre_processor_.SetTargetResolution(width, height, frame_rate);
    136 }
    137 
    138 void VideoProcessingImpl::SetTargetFramerate(int frame_rate) {
    139   rtc::CritScope cs(&mutex_);
    140   frame_pre_processor_.SetTargetFramerate(frame_rate);
    141 }
    142 
    143 uint32_t VideoProcessingImpl::GetDecimatedFrameRate() {
    144   rtc::CritScope cs(&mutex_);
    145   return frame_pre_processor_.GetDecimatedFrameRate();
    146 }
    147 
    148 uint32_t VideoProcessingImpl::GetDecimatedWidth() const {
    149   rtc::CritScope cs(&mutex_);
    150   return frame_pre_processor_.GetDecimatedWidth();
    151 }
    152 
    153 uint32_t VideoProcessingImpl::GetDecimatedHeight() const {
    154   rtc::CritScope cs(&mutex_);
    155   return frame_pre_processor_.GetDecimatedHeight();
    156 }
    157 
    158 void VideoProcessingImpl::EnableDenosing(bool enable) {
    159   rtc::CritScope cs(&mutex_);
    160   frame_pre_processor_.EnableDenosing(enable);
    161 }
    162 
    163 const VideoFrame* VideoProcessingImpl::PreprocessFrame(
    164     const VideoFrame& frame) {
    165   rtc::CritScope mutex(&mutex_);
    166   return frame_pre_processor_.PreprocessFrame(frame);
    167 }
    168 
    169 VideoContentMetrics* VideoProcessingImpl::GetContentMetrics() const {
    170   rtc::CritScope mutex(&mutex_);
    171   return frame_pre_processor_.GetContentMetrics();
    172 }
    173 
    174 void VideoProcessingImpl::EnableContentAnalysis(bool enable) {
    175   rtc::CritScope mutex(&mutex_);
    176   frame_pre_processor_.EnableContentAnalysis(enable);
    177 }
    178 
    179 }  // namespace webrtc
    180