Home | History | Annotate | Download | only in source
      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   denoising_.ChangeUniqueId(id);
     55   frame_pre_processor_.ChangeUniqueId(id);
     56   return VPM_OK;
     57 }
     58 
     59 int32_t VideoProcessingModuleImpl::Id() const {
     60   CriticalSectionScoped mutex(&mutex_);
     61   return id_;
     62 }
     63 
     64 VideoProcessingModuleImpl::VideoProcessingModuleImpl(const int32_t id)
     65     : id_(id),
     66     mutex_(*CriticalSectionWrapper::CreateCriticalSection()) {
     67   brightness_detection_.ChangeUniqueId(id);
     68   deflickering_.ChangeUniqueId(id);
     69   denoising_.ChangeUniqueId(id);
     70   frame_pre_processor_.ChangeUniqueId(id);
     71 }
     72 
     73 VideoProcessingModuleImpl::~VideoProcessingModuleImpl() {
     74   delete &mutex_;
     75 }
     76 
     77 void VideoProcessingModuleImpl::Reset() {
     78   CriticalSectionScoped mutex(&mutex_);
     79   deflickering_.Reset();
     80   denoising_.Reset();
     81   brightness_detection_.Reset();
     82   frame_pre_processor_.Reset();
     83 }
     84 
     85 int32_t VideoProcessingModule::GetFrameStats(FrameStats* stats,
     86                                              const I420VideoFrame& frame) {
     87   if (frame.IsZeroSize()) {
     88     LOG(LS_ERROR) << "Zero size frame.";
     89     return VPM_PARAMETER_ERROR;
     90   }
     91 
     92   int width = frame.width();
     93   int height = frame.height();
     94 
     95   ClearFrameStats(stats);  // The histogram needs to be zeroed out.
     96   SetSubSampling(stats, width, height);
     97 
     98   const uint8_t* buffer = frame.buffer(kYPlane);
     99   // Compute histogram and sum of frame
    100   for (int i = 0; i < height; i += (1 << stats->subSamplHeight)) {
    101     int k = i * width;
    102     for (int j = 0; j < width; j += (1 << stats->subSamplWidth)) {
    103       stats->hist[buffer[k + j]]++;
    104       stats->sum += buffer[k + j];
    105     }
    106   }
    107 
    108   stats->num_pixels = (width * height) / ((1 << stats->subSamplWidth) *
    109                      (1 << stats->subSamplHeight));
    110   assert(stats->num_pixels > 0);
    111 
    112   // Compute mean value of frame
    113   stats->mean = stats->sum / stats->num_pixels;
    114 
    115   return VPM_OK;
    116 }
    117 
    118 bool VideoProcessingModule::ValidFrameStats(const FrameStats& stats) {
    119   if (stats.num_pixels == 0) {
    120     LOG(LS_WARNING) << "Invalid frame stats.";
    121     return false;
    122   }
    123   return true;
    124 }
    125 
    126 void VideoProcessingModule::ClearFrameStats(FrameStats* stats) {
    127   stats->mean = 0;
    128   stats->sum = 0;
    129   stats->num_pixels = 0;
    130   stats->subSamplWidth = 0;
    131   stats->subSamplHeight = 0;
    132   memset(stats->hist, 0, sizeof(stats->hist));
    133 }
    134 
    135 int32_t VideoProcessingModule::ColorEnhancement(I420VideoFrame* frame) {
    136   return VideoProcessing::ColorEnhancement(frame);
    137 }
    138 
    139 int32_t VideoProcessingModule::Brighten(I420VideoFrame* frame, int delta) {
    140   return VideoProcessing::Brighten(frame, delta);
    141 }
    142 
    143 int32_t VideoProcessingModuleImpl::Deflickering(I420VideoFrame* frame,
    144                                                 FrameStats* stats) {
    145   CriticalSectionScoped mutex(&mutex_);
    146   return deflickering_.ProcessFrame(frame, stats);
    147 }
    148 
    149 int32_t VideoProcessingModuleImpl::Denoising(I420VideoFrame* frame) {
    150   CriticalSectionScoped mutex(&mutex_);
    151   return denoising_.ProcessFrame(frame);
    152 }
    153 
    154 int32_t VideoProcessingModuleImpl::BrightnessDetection(
    155   const I420VideoFrame& frame,
    156   const FrameStats& stats) {
    157   CriticalSectionScoped mutex(&mutex_);
    158   return brightness_detection_.ProcessFrame(frame, stats);
    159 }
    160 
    161 
    162 void VideoProcessingModuleImpl::EnableTemporalDecimation(bool enable) {
    163   CriticalSectionScoped mutex(&mutex_);
    164   frame_pre_processor_.EnableTemporalDecimation(enable);
    165 }
    166 
    167 
    168 void VideoProcessingModuleImpl::SetInputFrameResampleMode(VideoFrameResampling
    169                                                           resampling_mode) {
    170   CriticalSectionScoped cs(&mutex_);
    171   frame_pre_processor_.SetInputFrameResampleMode(resampling_mode);
    172 }
    173 
    174 int32_t VideoProcessingModuleImpl::SetTargetResolution(uint32_t width,
    175                                                        uint32_t height,
    176                                                        uint32_t frame_rate) {
    177   CriticalSectionScoped cs(&mutex_);
    178   return frame_pre_processor_.SetTargetResolution(width, height, frame_rate);
    179 }
    180 
    181 uint32_t VideoProcessingModuleImpl::Decimatedframe_rate() {
    182   CriticalSectionScoped cs(&mutex_);
    183   return  frame_pre_processor_.Decimatedframe_rate();
    184 }
    185 
    186 uint32_t VideoProcessingModuleImpl::DecimatedWidth() const {
    187   CriticalSectionScoped cs(&mutex_);
    188   return frame_pre_processor_.DecimatedWidth();
    189 }
    190 
    191 uint32_t VideoProcessingModuleImpl::DecimatedHeight() const {
    192   CriticalSectionScoped cs(&mutex_);
    193   return frame_pre_processor_.DecimatedHeight();
    194 }
    195 
    196 int32_t VideoProcessingModuleImpl::PreprocessFrame(
    197     const I420VideoFrame& frame,
    198     I420VideoFrame **processed_frame) {
    199   CriticalSectionScoped mutex(&mutex_);
    200   return frame_pre_processor_.PreprocessFrame(frame, processed_frame);
    201 }
    202 
    203 VideoContentMetrics* VideoProcessingModuleImpl::ContentMetrics() const {
    204   CriticalSectionScoped mutex(&mutex_);
    205   return frame_pre_processor_.ContentMetrics();
    206 }
    207 
    208 void VideoProcessingModuleImpl::EnableContentAnalysis(bool enable) {
    209   CriticalSectionScoped mutex(&mutex_);
    210   frame_pre_processor_.EnableContentAnalysis(enable);
    211 }
    212 
    213 }  // namespace webrtc
    214