Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(768)

Side by Side Diff: webrtc/media/base/videoadapter.cc

Issue 1982983003: VideoAdapter: Drop frames based on actual fps instead of expected fps (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Add jitter test Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/media/base/videoadapter.h ('k') | webrtc/media/base/videoadapter_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2010 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2010 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/media/base/videoadapter.h" 11 #include "webrtc/media/base/videoadapter.h"
12 12
13 #include <algorithm> 13 #include <algorithm>
14 #include <cstdlib>
14 #include <limits> 15 #include <limits>
15 16
16 #include "webrtc/base/checks.h" 17 #include "webrtc/base/checks.h"
17 #include "webrtc/base/logging.h" 18 #include "webrtc/base/logging.h"
18 #include "webrtc/media/base/mediaconstants.h" 19 #include "webrtc/media/base/mediaconstants.h"
19 #include "webrtc/media/base/videocommon.h" 20 #include "webrtc/media/base/videocommon.h"
20 21
21 namespace { 22 namespace {
22 23
23 struct Fraction { 24 struct Fraction {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 112
112 namespace cricket { 113 namespace cricket {
113 114
114 VideoAdapter::VideoAdapter() 115 VideoAdapter::VideoAdapter()
115 : frames_in_(0), 116 : frames_in_(0),
116 frames_out_(0), 117 frames_out_(0),
117 frames_scaled_(0), 118 frames_scaled_(0),
118 adaption_changes_(0), 119 adaption_changes_(0),
119 previous_width_(0), 120 previous_width_(0),
120 previous_height_(0), 121 previous_height_(0),
121 input_interval_(0),
122 interval_next_frame_(0),
123 resolution_request_max_pixel_count_(std::numeric_limits<int>::max()), 122 resolution_request_max_pixel_count_(std::numeric_limits<int>::max()),
124 resolution_request_max_pixel_count_step_up_(0) {} 123 resolution_request_max_pixel_count_step_up_(0) {}
125 124
126 VideoAdapter::~VideoAdapter() {} 125 VideoAdapter::~VideoAdapter() {}
127 126
128 void VideoAdapter::SetExpectedInputFrameInterval(int64_t interval) { 127 bool VideoAdapter::KeepFrame(int64_t in_timestamp_ns) {
129 // TODO(perkj): Consider measuring input frame rate instead.
130 // Frame rate typically varies depending on lighting.
131 rtc::CritScope cs(&critical_section_); 128 rtc::CritScope cs(&critical_section_);
132 input_interval_ = interval; 129 if (!requested_format_ || requested_format_->interval == 0)
130 return true;
131
132 if (next_frame_timestamp_ns_) {
133 // Time until next frame should be outputted.
134 const int64_t time_until_next_frame_ns =
135 (*next_frame_timestamp_ns_ - in_timestamp_ns);
136
137 // Continue if timestamp is withing expected range.
138 if (std::abs(time_until_next_frame_ns) < 2 * requested_format_->interval) {
139 // Drop if a frame shouldn't be outputted yet.
140 if (time_until_next_frame_ns > 0)
141 return false;
142 // Time to output new frame.
143 *next_frame_timestamp_ns_ += requested_format_->interval;
144 return true;
145 }
146 }
147
148 // First timestamp received or timestamp is way outside expected range, so
149 // reset. Set first timestamp target to just half the interval to prefer
150 // keeping frames in case of jitter.
151 next_frame_timestamp_ns_ =
152 rtc::Optional<int64_t>(in_timestamp_ns + requested_format_->interval / 2);
153 return true;
133 } 154 }
134 155
135 void VideoAdapter::AdaptFrameResolution(int in_width, 156 void VideoAdapter::AdaptFrameResolution(int in_width,
136 int in_height, 157 int in_height,
158 int64_t in_timestamp_ns,
137 int* cropped_width, 159 int* cropped_width,
138 int* cropped_height, 160 int* cropped_height,
139 int* out_width, 161 int* out_width,
140 int* out_height) { 162 int* out_height) {
141 rtc::CritScope cs(&critical_section_); 163 rtc::CritScope cs(&critical_section_);
142 ++frames_in_; 164 ++frames_in_;
143 165
144 // The max output pixel count is the minimum of the requests from 166 // The max output pixel count is the minimum of the requests from
145 // OnOutputFormatRequest and OnResolutionRequest. 167 // OnOutputFormatRequest and OnResolutionRequest.
146 int max_pixel_count = resolution_request_max_pixel_count_; 168 int max_pixel_count = resolution_request_max_pixel_count_;
147 if (requested_format_) { 169 if (requested_format_) {
148 max_pixel_count = std::min( 170 max_pixel_count = std::min(
149 max_pixel_count, requested_format_->width * requested_format_->height); 171 max_pixel_count, requested_format_->width * requested_format_->height);
150 } 172 }
151 173
152 // Drop the input frame if necessary. 174 // Drop the input frame if necessary.
153 bool should_drop = false; 175 if (max_pixel_count == 0 || !KeepFrame(in_timestamp_ns)) {
154 if (max_pixel_count == 0) {
155 // Drop all frames as the output format is 0x0.
156 should_drop = true;
157 } else if (requested_format_ && requested_format_->interval > 0) {
158 // Drop some frames based on input fps and output fps.
159 // Normally output fps is less than input fps.
160 interval_next_frame_ += input_interval_;
161 if (interval_next_frame_ >= requested_format_->interval) {
162 interval_next_frame_ -= requested_format_->interval;
163 // Reset |interval_next_frame_| if it accumulates too much to avoid
164 // "catching up" behaviour.
165 if (interval_next_frame_ >= requested_format_->interval)
166 interval_next_frame_ = 0;
167 } else {
168 should_drop = true;
169 }
170 }
171 if (should_drop) {
172 // Show VAdapt log every 90 frames dropped. (3 seconds) 176 // Show VAdapt log every 90 frames dropped. (3 seconds)
173 if ((frames_in_ - frames_out_) % 90 == 0) { 177 if ((frames_in_ - frames_out_) % 90 == 0) {
174 // TODO(fbarchard): Reduce to LS_VERBOSE when adapter info is not needed 178 // TODO(fbarchard): Reduce to LS_VERBOSE when adapter info is not needed
175 // in default calls. 179 // in default calls.
176 LOG(LS_INFO) << "VAdapt Drop Frame: scaled " << frames_scaled_ 180 LOG(LS_INFO) << "VAdapt Drop Frame: scaled " << frames_scaled_
177 << " / out " << frames_out_ 181 << " / out " << frames_out_
178 << " / in " << frames_in_ 182 << " / in " << frames_in_
179 << " Changes: " << adaption_changes_ 183 << " Changes: " << adaption_changes_
180 << " Input: " << in_width 184 << " Input: " << in_width
181 << "x" << in_height 185 << "x" << in_height
182 << " i" << input_interval_ 186 << " timestamp: " << in_timestamp_ns
183 << " Output: i" 187 << " Output: i"
184 << (requested_format_ ? requested_format_->interval : 0); 188 << (requested_format_ ? requested_format_->interval : 0);
185 } 189 }
186 190
187 // Drop frame. 191 // Drop frame.
188 *cropped_width = 0; 192 *cropped_width = 0;
189 *cropped_height = 0; 193 *cropped_height = 0;
190 *out_width = 0; 194 *out_width = 0;
191 *out_height = 0; 195 *out_height = 0;
192 return; 196 return;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 ++frames_out_; 235 ++frames_out_;
232 if (scale.numerator != scale.denominator) 236 if (scale.numerator != scale.denominator)
233 ++frames_scaled_; 237 ++frames_scaled_;
234 238
235 if (previous_width_ && (previous_width_ != *out_width || 239 if (previous_width_ && (previous_width_ != *out_width ||
236 previous_height_ != *out_height)) { 240 previous_height_ != *out_height)) {
237 ++adaption_changes_; 241 ++adaption_changes_;
238 LOG(LS_INFO) << "Frame size changed: scaled " << frames_scaled_ << " / out " 242 LOG(LS_INFO) << "Frame size changed: scaled " << frames_scaled_ << " / out "
239 << frames_out_ << " / in " << frames_in_ 243 << frames_out_ << " / in " << frames_in_
240 << " Changes: " << adaption_changes_ << " Input: " << in_width 244 << " Changes: " << adaption_changes_ << " Input: " << in_width
241 << "x" << in_height << " i" << input_interval_ 245 << "x" << in_height
242 << " Scale: " << scale.numerator << "/" << scale.denominator 246 << " Scale: " << scale.numerator << "/" << scale.denominator
243 << " Output: " << *out_width << "x" << *out_height << " i" 247 << " Output: " << *out_width << "x" << *out_height << " i"
244 << (requested_format_ ? requested_format_->interval : 0); 248 << (requested_format_ ? requested_format_->interval : 0);
245 } 249 }
246 250
247 previous_width_ = *out_width; 251 previous_width_ = *out_width;
248 previous_height_ = *out_height; 252 previous_height_ = *out_height;
249 } 253 }
250 254
251 void VideoAdapter::OnOutputFormatRequest(const VideoFormat& format) { 255 void VideoAdapter::OnOutputFormatRequest(const VideoFormat& format) {
252 rtc::CritScope cs(&critical_section_); 256 rtc::CritScope cs(&critical_section_);
253 requested_format_ = rtc::Optional<VideoFormat>(format); 257 requested_format_ = rtc::Optional<VideoFormat>(format);
254 interval_next_frame_ = 0; 258 next_frame_timestamp_ns_ = rtc::Optional<int64_t>();
255 } 259 }
256 260
257 void VideoAdapter::OnResolutionRequest( 261 void VideoAdapter::OnResolutionRequest(
258 rtc::Optional<int> max_pixel_count, 262 rtc::Optional<int> max_pixel_count,
259 rtc::Optional<int> max_pixel_count_step_up) { 263 rtc::Optional<int> max_pixel_count_step_up) {
260 rtc::CritScope cs(&critical_section_); 264 rtc::CritScope cs(&critical_section_);
261 resolution_request_max_pixel_count_ = 265 resolution_request_max_pixel_count_ =
262 max_pixel_count.value_or(std::numeric_limits<int>::max()); 266 max_pixel_count.value_or(std::numeric_limits<int>::max());
263 resolution_request_max_pixel_count_step_up_ = 267 resolution_request_max_pixel_count_step_up_ =
264 max_pixel_count_step_up.value_or(0); 268 max_pixel_count_step_up.value_or(0);
265 } 269 }
266 270
267 } // namespace cricket 271 } // namespace cricket
OLDNEW
« no previous file with comments | « webrtc/media/base/videoadapter.h ('k') | webrtc/media/base/videoadapter_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698