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

Side by Side Diff: content/renderer/media/video_track_adapter.cc

Issue 2870413004: Detect frames from rotated devices in VideoTrackAdapter on Android. (Closed)
Patch Set: Created 3 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 | « content/renderer/media/video_track_adapter.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/renderer/media/video_track_adapter.h" 5 #include "content/renderer/media/video_track_adapter.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <memory> 9 #include <memory>
10 #include <string> 10 #include <string>
11 #include <utility> 11 #include <utility>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/command_line.h" 14 #include "base/command_line.h"
15 #include "base/location.h" 15 #include "base/location.h"
16 #include "base/macros.h" 16 #include "base/macros.h"
17 #include "base/metrics/histogram_macros.h" 17 #include "base/metrics/histogram_macros.h"
18 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_number_conversions.h"
19 #include "base/threading/thread_task_runner_handle.h" 19 #include "base/threading/thread_task_runner_handle.h"
20 #include "base/trace_event/trace_event.h" 20 #include "base/trace_event/trace_event.h"
21 #include "build/build_config.h"
21 #include "content/public/common/content_switches.h" 22 #include "content/public/common/content_switches.h"
22 #include "media/base/bind_to_current_loop.h" 23 #include "media/base/bind_to_current_loop.h"
23 #include "media/base/video_util.h" 24 #include "media/base/video_util.h"
24 25
25 namespace content { 26 namespace content {
26 27
27 namespace { 28 namespace {
28 29
29 // Amount of frame intervals to wait before considering the source as muted, for 30 // Amount of frame intervals to wait before considering the source as muted, for
30 // the first frame and under normal conditions, respectively. First frame might 31 // the first frame and under normal conditions, respectively. First frame might
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 float source_frame_rate); 96 float source_frame_rate);
96 97
97 // Bound to the IO-thread. 98 // Bound to the IO-thread.
98 base::ThreadChecker io_thread_checker_; 99 base::ThreadChecker io_thread_checker_;
99 100
100 // The task runner where we will release VideoCaptureDeliverFrameCB 101 // The task runner where we will release VideoCaptureDeliverFrameCB
101 // registered in AddCallback. 102 // registered in AddCallback.
102 const scoped_refptr<base::SingleThreadTaskRunner> renderer_task_runner_; 103 const scoped_refptr<base::SingleThreadTaskRunner> renderer_task_runner_;
103 104
104 const gfx::Size max_frame_size_; 105 const gfx::Size max_frame_size_;
106 base::Optional<gfx::Size> expected_native_size_;
105 const double min_aspect_ratio_; 107 const double min_aspect_ratio_;
106 const double max_aspect_ratio_; 108 const double max_aspect_ratio_;
107 109
108 double frame_rate_; 110 double frame_rate_;
109 base::TimeDelta last_time_stamp_; 111 base::TimeDelta last_time_stamp_;
110 double max_frame_rate_; 112 double max_frame_rate_;
111 double keep_frame_counter_; 113 double keep_frame_counter_;
112 114
113 typedef std::pair<const MediaStreamVideoTrack*, VideoCaptureDeliverFrameCB> 115 typedef std::pair<const MediaStreamVideoTrack*, VideoCaptureDeliverFrameCB>
114 VideoIdCallbackPair; 116 VideoIdCallbackPair;
115 std::vector<VideoIdCallbackPair> callbacks_; 117 std::vector<VideoIdCallbackPair> callbacks_;
116 118
117 DISALLOW_COPY_AND_ASSIGN(VideoFrameResolutionAdapter); 119 DISALLOW_COPY_AND_ASSIGN(VideoFrameResolutionAdapter);
118 }; 120 };
119 121
120 VideoTrackAdapter::VideoFrameResolutionAdapter::VideoFrameResolutionAdapter( 122 VideoTrackAdapter::VideoFrameResolutionAdapter::VideoFrameResolutionAdapter(
121 scoped_refptr<base::SingleThreadTaskRunner> render_message_loop, 123 scoped_refptr<base::SingleThreadTaskRunner> render_message_loop,
122 const VideoTrackAdapterSettings& settings) 124 const VideoTrackAdapterSettings& settings)
123 : renderer_task_runner_(render_message_loop), 125 : renderer_task_runner_(render_message_loop),
124 max_frame_size_(settings.max_width, settings.max_height), 126 max_frame_size_(settings.max_width, settings.max_height),
127 expected_native_size_(settings.expected_native_size),
125 min_aspect_ratio_(settings.min_aspect_ratio), 128 min_aspect_ratio_(settings.min_aspect_ratio),
126 max_aspect_ratio_(settings.max_aspect_ratio), 129 max_aspect_ratio_(settings.max_aspect_ratio),
127 frame_rate_(MediaStreamVideoSource::kDefaultFrameRate), 130 frame_rate_(MediaStreamVideoSource::kDefaultFrameRate),
128 last_time_stamp_(base::TimeDelta::Max()), 131 last_time_stamp_(base::TimeDelta::Max()),
129 max_frame_rate_(settings.max_frame_rate), 132 max_frame_rate_(settings.max_frame_rate),
130 keep_frame_counter_(0.0) { 133 keep_frame_counter_(0.0) {
131 DCHECK(renderer_task_runner_.get()); 134 DCHECK(renderer_task_runner_.get());
132 DCHECK(io_thread_checker_.CalledOnValidThread()); 135 DCHECK(io_thread_checker_.CalledOnValidThread());
133 DCHECK_GE(max_aspect_ratio_, min_aspect_ratio_); 136 DCHECK_GE(max_aspect_ratio_, min_aspect_ratio_);
134 CHECK_NE(0, max_aspect_ratio_); 137 CHECK_NE(0, max_aspect_ratio_);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 return; 212 return;
210 213
211 // TODO(perkj): Allow cropping / scaling of textures once 214 // TODO(perkj): Allow cropping / scaling of textures once
212 // http://crbug/362521 is fixed. 215 // http://crbug/362521 is fixed.
213 if (frame->HasTextures()) { 216 if (frame->HasTextures()) {
214 DoDeliverFrame(frame, estimated_capture_time); 217 DoDeliverFrame(frame, estimated_capture_time);
215 return; 218 return;
216 } 219 }
217 scoped_refptr<media::VideoFrame> video_frame(frame); 220 scoped_refptr<media::VideoFrame> video_frame(frame);
218 221
222 bool is_rotated = false;
223 #if defined(OS_ANDROID)
tommi (sloooow) - chröme 2017/05/15 19:15:44 this is the only OS_ check in this file afaict. If
Guido Urdaneta 2017/05/16 08:43:21 Done.
224 if (expected_native_size_ &&
225 frame->natural_size().width() == expected_native_size_->height() &&
226 frame->natural_size().height() == expected_native_size_->width()) {
227 is_rotated = true;
228 }
229 #endif
219 gfx::Size desired_size; 230 gfx::Size desired_size;
220 CalculateTargetSize(frame->natural_size(), max_frame_size_, min_aspect_ratio_, 231 CalculateTargetSize(is_rotated, frame->natural_size(), max_frame_size_,
221 max_aspect_ratio_, &desired_size); 232 min_aspect_ratio_, max_aspect_ratio_, &desired_size);
222 if (desired_size != frame->natural_size()) { 233 if (desired_size != frame->natural_size()) {
223 // Get the largest centered rectangle with the same aspect ratio of 234 // Get the largest centered rectangle with the same aspect ratio of
224 // |desired_size| that fits entirely inside of |frame->visible_rect()|. 235 // |desired_size| that fits entirely inside of |frame->visible_rect()|.
225 // This will be the rect we need to crop the original frame to. 236 // This will be the rect we need to crop the original frame to.
226 // From this rect, the original frame can be scaled down to |desired_size|. 237 // From this rect, the original frame can be scaled down to |desired_size|.
227 const gfx::Rect region_in_frame = 238 const gfx::Rect region_in_frame =
228 media::ComputeLetterboxRegion(frame->visible_rect(), desired_size); 239 media::ComputeLetterboxRegion(frame->visible_rect(), desired_size);
229 240
230 video_frame = media::VideoFrame::WrapVideoFrame( 241 video_frame = media::VideoFrame::WrapVideoFrame(
231 frame, frame->format(), region_in_frame, desired_size); 242 frame, frame->format(), region_in_frame, desired_size);
(...skipping 11 matching lines...) Expand all
243 DoDeliverFrame(video_frame, estimated_capture_time); 254 DoDeliverFrame(video_frame, estimated_capture_time);
244 } 255 }
245 256
246 bool VideoTrackAdapter::VideoFrameResolutionAdapter::SettingsMatch( 257 bool VideoTrackAdapter::VideoFrameResolutionAdapter::SettingsMatch(
247 const VideoTrackAdapterSettings& settings) const { 258 const VideoTrackAdapterSettings& settings) const {
248 DCHECK(io_thread_checker_.CalledOnValidThread()); 259 DCHECK(io_thread_checker_.CalledOnValidThread());
249 return max_frame_size_.width() == settings.max_width && 260 return max_frame_size_.width() == settings.max_width &&
250 max_frame_size_.height() == settings.max_height && 261 max_frame_size_.height() == settings.max_height &&
251 min_aspect_ratio_ == settings.min_aspect_ratio && 262 min_aspect_ratio_ == settings.min_aspect_ratio &&
252 max_aspect_ratio_ == settings.max_aspect_ratio && 263 max_aspect_ratio_ == settings.max_aspect_ratio &&
253 max_frame_rate_ == settings.max_frame_rate; 264 max_frame_rate_ == settings.max_frame_rate &&
265 expected_native_size_ == settings.expected_native_size;
254 } 266 }
255 267
256 bool VideoTrackAdapter::VideoFrameResolutionAdapter::IsEmpty() const { 268 bool VideoTrackAdapter::VideoFrameResolutionAdapter::IsEmpty() const {
257 DCHECK(io_thread_checker_.CalledOnValidThread()); 269 DCHECK(io_thread_checker_.CalledOnValidThread());
258 return callbacks_.empty(); 270 return callbacks_.empty();
259 } 271 }
260 272
261 void VideoTrackAdapter::VideoFrameResolutionAdapter::DoDeliverFrame( 273 void VideoTrackAdapter::VideoFrameResolutionAdapter::DoDeliverFrame(
262 const scoped_refptr<media::VideoFrame>& frame, 274 const scoped_refptr<media::VideoFrame>& frame,
263 const base::TimeTicks& estimated_capture_time) { 275 const base::TimeTicks& estimated_capture_time) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 } 334 }
323 DVLOG(3) << "Drop frame. Input frame_rate_ " << frame_rate_ << "."; 335 DVLOG(3) << "Drop frame. Input frame_rate_ " << frame_rate_ << ".";
324 return true; 336 return true;
325 } 337 }
326 338
327 VideoTrackAdapterSettings::VideoTrackAdapterSettings() 339 VideoTrackAdapterSettings::VideoTrackAdapterSettings()
328 : VideoTrackAdapterSettings(std::numeric_limits<int>::max(), 340 : VideoTrackAdapterSettings(std::numeric_limits<int>::max(),
329 std::numeric_limits<int>::max(), 341 std::numeric_limits<int>::max(),
330 0.0, 342 0.0,
331 std::numeric_limits<double>::max(), 343 std::numeric_limits<double>::max(),
332 0.0) {} 344 0.0,
345 base::Optional<gfx::Size>()) {}
333 346
334 VideoTrackAdapterSettings::VideoTrackAdapterSettings(int max_width, 347 VideoTrackAdapterSettings::VideoTrackAdapterSettings(
335 int max_height, 348 int max_width,
336 double min_aspect_ratio, 349 int max_height,
337 double max_aspect_ratio, 350 double min_aspect_ratio,
338 double max_frame_rate) 351 double max_aspect_ratio,
352 double max_frame_rate,
353 const base::Optional<gfx::Size>& expected_native_size)
339 : max_width(max_width), 354 : max_width(max_width),
340 max_height(max_height), 355 max_height(max_height),
341 min_aspect_ratio(min_aspect_ratio), 356 min_aspect_ratio(min_aspect_ratio),
342 max_aspect_ratio(max_aspect_ratio), 357 max_aspect_ratio(max_aspect_ratio),
343 max_frame_rate(max_frame_rate) { 358 max_frame_rate(max_frame_rate),
359 expected_native_size(expected_native_size) {
344 DCHECK_GE(max_width, 1); 360 DCHECK_GE(max_width, 1);
345 DCHECK_GE(max_height, 1); 361 DCHECK_GE(max_height, 1);
346 DCHECK_GE(min_aspect_ratio, 0.0); 362 DCHECK_GE(min_aspect_ratio, 0.0);
347 DCHECK_GE(max_aspect_ratio, min_aspect_ratio); 363 DCHECK_GE(max_aspect_ratio, min_aspect_ratio);
348 DCHECK_GE(max_frame_rate, 0.0); 364 DCHECK_GE(max_frame_rate, 0.0);
349 } 365 }
350 366
367 VideoTrackAdapterSettings::VideoTrackAdapterSettings(
368 const VideoTrackAdapterSettings& other) = default;
369 VideoTrackAdapterSettings& VideoTrackAdapterSettings::operator=(
370 const VideoTrackAdapterSettings& other) = default;
371
351 VideoTrackAdapter::VideoTrackAdapter( 372 VideoTrackAdapter::VideoTrackAdapter(
352 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) 373 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
353 : io_task_runner_(io_task_runner), 374 : io_task_runner_(io_task_runner),
354 renderer_task_runner_(base::ThreadTaskRunnerHandle::Get()), 375 renderer_task_runner_(base::ThreadTaskRunnerHandle::Get()),
355 monitoring_frame_rate_(false), 376 monitoring_frame_rate_(false),
356 muted_state_(false), 377 muted_state_(false),
357 frame_counter_(0), 378 frame_counter_(0),
358 source_frame_rate_(0.0f) { 379 source_frame_rate_(0.0f) {
359 DCHECK(io_task_runner); 380 DCHECK(io_task_runner);
360 } 381 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 bound_on_muted_callback, source_frame_rate)); 433 bound_on_muted_callback, source_frame_rate));
413 } 434 }
414 435
415 void VideoTrackAdapter::StopFrameMonitoring() { 436 void VideoTrackAdapter::StopFrameMonitoring() {
416 DCHECK(thread_checker_.CalledOnValidThread()); 437 DCHECK(thread_checker_.CalledOnValidThread());
417 io_task_runner_->PostTask( 438 io_task_runner_->PostTask(
418 FROM_HERE, base::Bind(&VideoTrackAdapter::StopFrameMonitoringOnIO, this)); 439 FROM_HERE, base::Bind(&VideoTrackAdapter::StopFrameMonitoringOnIO, this));
419 } 440 }
420 441
421 // static 442 // static
422 void VideoTrackAdapter::CalculateTargetSize(const gfx::Size& input_size, 443 void VideoTrackAdapter::CalculateTargetSize(
423 const gfx::Size& max_frame_size, 444 bool is_rotated,
424 double min_aspect_ratio, 445 const gfx::Size& original_input_size,
425 double max_aspect_ratio, 446 const gfx::Size& max_frame_size,
426 gfx::Size* desired_size) { 447 double min_aspect_ratio,
448 double max_aspect_ratio,
449 gfx::Size* desired_size) {
450 const gfx::Size& input_size =
451 is_rotated
452 ? gfx::Size(original_input_size.height(), original_input_size.width())
453 : original_input_size;
454
427 // If |frame| has larger width or height than requested, or the aspect ratio 455 // If |frame| has larger width or height than requested, or the aspect ratio
428 // does not match the requested, we want to create a wrapped version of this 456 // does not match the requested, we want to create a wrapped version of this
429 // frame with a size that fulfills the constraints. 457 // frame with a size that fulfills the constraints.
430 const double input_ratio = 458 const double input_ratio =
431 static_cast<double>(input_size.width()) / input_size.height(); 459 static_cast<double>(input_size.width()) / input_size.height();
432 460
433 if (input_size.width() > max_frame_size.width() || 461 if (input_size.width() > max_frame_size.width() ||
434 input_size.height() > max_frame_size.height() || 462 input_size.height() > max_frame_size.height() ||
435 input_ratio > max_aspect_ratio || input_ratio < min_aspect_ratio) { 463 input_ratio > max_aspect_ratio || input_ratio < min_aspect_ratio) {
436 int desired_width = std::min(max_frame_size.width(), input_size.width()); 464 int desired_width = std::min(max_frame_size.width(), input_size.width());
(...skipping 10 matching lines...) Expand all
447 requested_ratio); 475 requested_ratio);
448 // Make sure we scale to an even height to avoid rounding errors 476 // Make sure we scale to an even height to avoid rounding errors
449 desired_height = (desired_height + 1) & ~1; 477 desired_height = (desired_height + 1) & ~1;
450 } else if (resulting_ratio > requested_ratio) { 478 } else if (resulting_ratio > requested_ratio) {
451 desired_width = 479 desired_width =
452 static_cast<int>((desired_width * requested_ratio) / resulting_ratio); 480 static_cast<int>((desired_width * requested_ratio) / resulting_ratio);
453 // Make sure we scale to an even width to avoid rounding errors. 481 // Make sure we scale to an even width to avoid rounding errors.
454 desired_width = (desired_width + 1) & ~1; 482 desired_width = (desired_width + 1) & ~1;
455 } 483 }
456 484
457 *desired_size = gfx::Size(desired_width, desired_height); 485 *desired_size = is_rotated ? gfx::Size(desired_height, desired_width)
486 : gfx::Size(desired_width, desired_height);
458 } else { 487 } else {
459 *desired_size = input_size; 488 *desired_size = original_input_size;
460 } 489 }
461 } 490 }
462 491
463 void VideoTrackAdapter::StartFrameMonitoringOnIO( 492 void VideoTrackAdapter::StartFrameMonitoringOnIO(
464 const OnMutedCallback& on_muted_callback, 493 const OnMutedCallback& on_muted_callback,
465 double source_frame_rate) { 494 double source_frame_rate) {
466 DCHECK(io_task_runner_->BelongsToCurrentThread()); 495 DCHECK(io_task_runner_->BelongsToCurrentThread());
467 DCHECK(!monitoring_frame_rate_); 496 DCHECK(!monitoring_frame_rate_);
468 497
469 monitoring_frame_rate_ = true; 498 monitoring_frame_rate_ = true;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 } 555 }
527 556
528 io_task_runner_->PostDelayedTask( 557 io_task_runner_->PostDelayedTask(
529 FROM_HERE, base::Bind(&VideoTrackAdapter::CheckFramesReceivedOnIO, this, 558 FROM_HERE, base::Bind(&VideoTrackAdapter::CheckFramesReceivedOnIO, this,
530 set_muted_state_callback, frame_counter_), 559 set_muted_state_callback, frame_counter_),
531 base::TimeDelta::FromSecondsD(kNormalFrameTimeoutInFrameIntervals / 560 base::TimeDelta::FromSecondsD(kNormalFrameTimeoutInFrameIntervals /
532 source_frame_rate_)); 561 source_frame_rate_));
533 } 562 }
534 563
535 } // namespace content 564 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/video_track_adapter.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698