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/main/source/frame_preprocessor.h"
12
13 namespace webrtc {
14
VPMFramePreprocessor()15 VPMFramePreprocessor::VPMFramePreprocessor()
16 : id_(0),
17 content_metrics_(NULL),
18 resampled_frame_(),
19 enable_ca_(false),
20 frame_cnt_(0) {
21 spatial_resampler_ = new VPMSimpleSpatialResampler();
22 ca_ = new VPMContentAnalysis(true);
23 vd_ = new VPMVideoDecimator();
24 }
25
~VPMFramePreprocessor()26 VPMFramePreprocessor::~VPMFramePreprocessor() {
27 Reset();
28 delete spatial_resampler_;
29 delete ca_;
30 delete vd_;
31 }
32
ChangeUniqueId(const int32_t id)33 int32_t VPMFramePreprocessor::ChangeUniqueId(const int32_t id) {
34 id_ = id;
35 return VPM_OK;
36 }
37
Reset()38 void VPMFramePreprocessor::Reset() {
39 ca_->Release();
40 vd_->Reset();
41 content_metrics_ = NULL;
42 spatial_resampler_->Reset();
43 enable_ca_ = false;
44 frame_cnt_ = 0;
45 }
46
47
EnableTemporalDecimation(bool enable)48 void VPMFramePreprocessor::EnableTemporalDecimation(bool enable) {
49 vd_->EnableTemporalDecimation(enable);
50 }
51
EnableContentAnalysis(bool enable)52 void VPMFramePreprocessor::EnableContentAnalysis(bool enable) {
53 enable_ca_ = enable;
54 }
55
SetInputFrameResampleMode(VideoFrameResampling resampling_mode)56 void VPMFramePreprocessor::SetInputFrameResampleMode(
57 VideoFrameResampling resampling_mode) {
58 spatial_resampler_->SetInputFrameResampleMode(resampling_mode);
59 }
60
SetTargetResolution(uint32_t width,uint32_t height,uint32_t frame_rate)61 int32_t VPMFramePreprocessor::SetTargetResolution(
62 uint32_t width, uint32_t height, uint32_t frame_rate) {
63 if ( (width == 0) || (height == 0) || (frame_rate == 0)) {
64 return VPM_PARAMETER_ERROR;
65 }
66 int32_t ret_val = 0;
67 ret_val = spatial_resampler_->SetTargetFrameSize(width, height);
68
69 if (ret_val < 0) return ret_val;
70
71 ret_val = vd_->SetTargetFramerate(frame_rate);
72 if (ret_val < 0) return ret_val;
73
74 return VPM_OK;
75 }
76
UpdateIncomingframe_rate()77 void VPMFramePreprocessor::UpdateIncomingframe_rate() {
78 vd_->UpdateIncomingframe_rate();
79 }
80
Decimatedframe_rate()81 uint32_t VPMFramePreprocessor::Decimatedframe_rate() {
82 return vd_->Decimatedframe_rate();
83 }
84
85
DecimatedWidth() const86 uint32_t VPMFramePreprocessor::DecimatedWidth() const {
87 return spatial_resampler_->TargetWidth();
88 }
89
90
DecimatedHeight() const91 uint32_t VPMFramePreprocessor::DecimatedHeight() const {
92 return spatial_resampler_->TargetHeight();
93 }
94
95
PreprocessFrame(const I420VideoFrame & frame,I420VideoFrame ** processed_frame)96 int32_t VPMFramePreprocessor::PreprocessFrame(const I420VideoFrame& frame,
97 I420VideoFrame** processed_frame) {
98 if (frame.IsZeroSize()) {
99 return VPM_PARAMETER_ERROR;
100 }
101
102 vd_->UpdateIncomingframe_rate();
103
104 if (vd_->DropFrame()) {
105 return 1; // drop 1 frame
106 }
107
108 // Resizing incoming frame if needed. Otherwise, remains NULL.
109 // We are not allowed to resample the input frame (must make a copy of it).
110 *processed_frame = NULL;
111 if (spatial_resampler_->ApplyResample(frame.width(), frame.height())) {
112 int32_t ret = spatial_resampler_->ResampleFrame(frame, &resampled_frame_);
113 if (ret != VPM_OK) return ret;
114 *processed_frame = &resampled_frame_;
115 }
116
117 // Perform content analysis on the frame to be encoded.
118 if (enable_ca_) {
119 // Compute new metrics every |kSkipFramesCA| frames, starting with
120 // the first frame.
121 if (frame_cnt_ % kSkipFrameCA == 0) {
122 if (*processed_frame == NULL) {
123 content_metrics_ = ca_->ComputeContentMetrics(frame);
124 } else {
125 content_metrics_ = ca_->ComputeContentMetrics(resampled_frame_);
126 }
127 }
128 ++frame_cnt_;
129 }
130 return VPM_OK;
131 }
132
ContentMetrics() const133 VideoContentMetrics* VPMFramePreprocessor::ContentMetrics() const {
134 return content_metrics_;
135 }
136
137 } // namespace
138