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/frame_preprocessor.h"
     12 
     13 #include "webrtc/modules/video_processing/video_denoiser.h"
     14 
     15 namespace webrtc {
     16 
     17 VPMFramePreprocessor::VPMFramePreprocessor()
     18     : content_metrics_(nullptr),
     19       resampled_frame_(),
     20       enable_ca_(false),
     21       frame_cnt_(0) {
     22   spatial_resampler_ = new VPMSimpleSpatialResampler();
     23   ca_ = new VPMContentAnalysis(true);
     24   vd_ = new VPMVideoDecimator();
     25 }
     26 
     27 VPMFramePreprocessor::~VPMFramePreprocessor() {
     28   Reset();
     29   delete ca_;
     30   delete vd_;
     31   delete spatial_resampler_;
     32 }
     33 
     34 void VPMFramePreprocessor::Reset() {
     35   ca_->Release();
     36   vd_->Reset();
     37   content_metrics_ = nullptr;
     38   spatial_resampler_->Reset();
     39   enable_ca_ = false;
     40   frame_cnt_ = 0;
     41 }
     42 
     43 void VPMFramePreprocessor::EnableTemporalDecimation(bool enable) {
     44   vd_->EnableTemporalDecimation(enable);
     45 }
     46 
     47 void VPMFramePreprocessor::EnableContentAnalysis(bool enable) {
     48   enable_ca_ = enable;
     49 }
     50 
     51 void VPMFramePreprocessor::SetInputFrameResampleMode(
     52     VideoFrameResampling resampling_mode) {
     53   spatial_resampler_->SetInputFrameResampleMode(resampling_mode);
     54 }
     55 
     56 int32_t VPMFramePreprocessor::SetTargetResolution(uint32_t width,
     57                                                   uint32_t height,
     58                                                   uint32_t frame_rate) {
     59   if ((width == 0) || (height == 0) || (frame_rate == 0)) {
     60     return VPM_PARAMETER_ERROR;
     61   }
     62   int32_t ret_val = 0;
     63   ret_val = spatial_resampler_->SetTargetFrameSize(width, height);
     64 
     65   if (ret_val < 0)
     66     return ret_val;
     67 
     68   vd_->SetTargetFramerate(frame_rate);
     69   return VPM_OK;
     70 }
     71 
     72 void VPMFramePreprocessor::SetTargetFramerate(int frame_rate) {
     73   if (frame_rate == -1) {
     74     vd_->EnableTemporalDecimation(false);
     75   } else {
     76     vd_->EnableTemporalDecimation(true);
     77     vd_->SetTargetFramerate(frame_rate);
     78   }
     79 }
     80 
     81 void VPMFramePreprocessor::UpdateIncomingframe_rate() {
     82   vd_->UpdateIncomingframe_rate();
     83 }
     84 
     85 uint32_t VPMFramePreprocessor::GetDecimatedFrameRate() {
     86   return vd_->GetDecimatedFrameRate();
     87 }
     88 
     89 uint32_t VPMFramePreprocessor::GetDecimatedWidth() const {
     90   return spatial_resampler_->TargetWidth();
     91 }
     92 
     93 uint32_t VPMFramePreprocessor::GetDecimatedHeight() const {
     94   return spatial_resampler_->TargetHeight();
     95 }
     96 
     97 void VPMFramePreprocessor::EnableDenosing(bool enable) {
     98   denoiser_.reset(new VideoDenoiser(true));
     99 }
    100 
    101 const VideoFrame* VPMFramePreprocessor::PreprocessFrame(
    102     const VideoFrame& frame) {
    103   if (frame.IsZeroSize()) {
    104     return nullptr;
    105   }
    106 
    107   vd_->UpdateIncomingframe_rate();
    108   if (vd_->DropFrame()) {
    109     return nullptr;
    110   }
    111 
    112   const VideoFrame* current_frame = &frame;
    113   if (denoiser_) {
    114     denoiser_->DenoiseFrame(*current_frame, &denoised_frame_);
    115     current_frame = &denoised_frame_;
    116   }
    117 
    118   if (spatial_resampler_->ApplyResample(current_frame->width(),
    119                                         current_frame->height())) {
    120     if (spatial_resampler_->ResampleFrame(*current_frame, &resampled_frame_) !=
    121         VPM_OK) {
    122       return nullptr;
    123     }
    124     current_frame = &resampled_frame_;
    125   }
    126 
    127   // Perform content analysis on the frame to be encoded.
    128   if (enable_ca_ && frame_cnt_ % kSkipFrameCA == 0) {
    129     // Compute new metrics every |kSkipFramesCA| frames, starting with
    130     // the first frame.
    131     content_metrics_ = ca_->ComputeContentMetrics(*current_frame);
    132   }
    133   ++frame_cnt_;
    134   return current_frame;
    135 }
    136 
    137 VideoContentMetrics* VPMFramePreprocessor::GetContentMetrics() const {
    138   return content_metrics_;
    139 }
    140 
    141 }  // namespace webrtc
    142