| OLD | NEW |
| 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 <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 if (MaybeDropFrame(frame, frame_rate)) | 216 if (MaybeDropFrame(frame, frame_rate)) |
| 217 return; | 217 return; |
| 218 | 218 |
| 219 // TODO(perkj): Allow cropping / scaling of textures once | 219 // TODO(perkj): Allow cropping / scaling of textures once |
| 220 // http://crbug/362521 is fixed. | 220 // http://crbug/362521 is fixed. |
| 221 if (frame->HasTextures()) { | 221 if (frame->HasTextures()) { |
| 222 DoDeliverFrame(frame, estimated_capture_time); | 222 DoDeliverFrame(frame, estimated_capture_time); |
| 223 return; | 223 return; |
| 224 } | 224 } |
| 225 scoped_refptr<media::VideoFrame> video_frame(frame); | 225 scoped_refptr<media::VideoFrame> video_frame(frame); |
| 226 const double input_ratio = | |
| 227 static_cast<double>(frame->natural_size().width()) / | |
| 228 frame->natural_size().height(); | |
| 229 | 226 |
| 230 // If |frame| has larger width or height than requested, or the aspect ratio | 227 gfx::Size desired_size; |
| 231 // does not match the requested, we want to create a wrapped version of this | 228 CalculateTargetSize(frame->natural_size(), max_frame_size_, min_aspect_ratio_, |
| 232 // frame with a size that fulfills the constraints. | 229 max_aspect_ratio_, &desired_size); |
| 233 if (frame->natural_size().width() > max_frame_size_.width() || | 230 if (desired_size != frame->natural_size()) { |
| 234 frame->natural_size().height() > max_frame_size_.height() || | |
| 235 input_ratio > max_aspect_ratio_ || | |
| 236 input_ratio < min_aspect_ratio_) { | |
| 237 int desired_width = std::min(max_frame_size_.width(), | |
| 238 frame->natural_size().width()); | |
| 239 int desired_height = std::min(max_frame_size_.height(), | |
| 240 frame->natural_size().height()); | |
| 241 | |
| 242 const double resulting_ratio = | |
| 243 static_cast<double>(desired_width) / desired_height; | |
| 244 // Make sure |min_aspect_ratio_| < |requested_ratio| < |max_aspect_ratio_|. | |
| 245 const double requested_ratio = std::max( | |
| 246 std::min(resulting_ratio, max_aspect_ratio_), min_aspect_ratio_); | |
| 247 | |
| 248 if (resulting_ratio < requested_ratio) { | |
| 249 desired_height = static_cast<int>((desired_height * resulting_ratio) / | |
| 250 requested_ratio); | |
| 251 // Make sure we scale to an even height to avoid rounding errors | |
| 252 desired_height = (desired_height + 1) & ~1; | |
| 253 } else if (resulting_ratio > requested_ratio) { | |
| 254 desired_width = static_cast<int>((desired_width * requested_ratio) / | |
| 255 resulting_ratio); | |
| 256 // Make sure we scale to an even width to avoid rounding errors. | |
| 257 desired_width = (desired_width + 1) & ~1; | |
| 258 } | |
| 259 | |
| 260 const gfx::Size desired_size(desired_width, desired_height); | |
| 261 | |
| 262 // Get the largest centered rectangle with the same aspect ratio of | 231 // Get the largest centered rectangle with the same aspect ratio of |
| 263 // |desired_size| that fits entirely inside of |frame->visible_rect()|. | 232 // |desired_size| that fits entirely inside of |frame->visible_rect()|. |
| 264 // This will be the rect we need to crop the original frame to. | 233 // This will be the rect we need to crop the original frame to. |
| 265 // From this rect, the original frame can be scaled down to |desired_size|. | 234 // From this rect, the original frame can be scaled down to |desired_size|. |
| 266 const gfx::Rect region_in_frame = | 235 const gfx::Rect region_in_frame = |
| 267 media::ComputeLetterboxRegion(frame->visible_rect(), desired_size); | 236 media::ComputeLetterboxRegion(frame->visible_rect(), desired_size); |
| 268 | 237 |
| 269 video_frame = media::VideoFrame::WrapVideoFrame( | 238 video_frame = media::VideoFrame::WrapVideoFrame( |
| 270 frame, frame->format(), region_in_frame, desired_size); | 239 frame, frame->format(), region_in_frame, desired_size); |
| 271 if (!video_frame) | 240 if (!video_frame) |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 FROM_HERE, base::Bind(&VideoTrackAdapter::StartFrameMonitoringOnIO, this, | 410 FROM_HERE, base::Bind(&VideoTrackAdapter::StartFrameMonitoringOnIO, this, |
| 442 bound_on_muted_callback, source_frame_rate)); | 411 bound_on_muted_callback, source_frame_rate)); |
| 443 } | 412 } |
| 444 | 413 |
| 445 void VideoTrackAdapter::StopFrameMonitoring() { | 414 void VideoTrackAdapter::StopFrameMonitoring() { |
| 446 DCHECK(thread_checker_.CalledOnValidThread()); | 415 DCHECK(thread_checker_.CalledOnValidThread()); |
| 447 io_task_runner_->PostTask( | 416 io_task_runner_->PostTask( |
| 448 FROM_HERE, base::Bind(&VideoTrackAdapter::StopFrameMonitoringOnIO, this)); | 417 FROM_HERE, base::Bind(&VideoTrackAdapter::StopFrameMonitoringOnIO, this)); |
| 449 } | 418 } |
| 450 | 419 |
| 420 // static |
| 421 void VideoTrackAdapter::CalculateTargetSize(const gfx::Size& input_size, |
| 422 const gfx::Size& max_frame_size, |
| 423 double min_aspect_ratio, |
| 424 double max_aspect_ratio, |
| 425 gfx::Size* desired_size) { |
| 426 // If |frame| has larger width or height than requested, or the aspect ratio |
| 427 // does not match the requested, we want to create a wrapped version of this |
| 428 // frame with a size that fulfills the constraints. |
| 429 const double input_ratio = |
| 430 static_cast<double>(input_size.width()) / input_size.height(); |
| 431 |
| 432 if (input_size.width() > max_frame_size.width() || |
| 433 input_size.height() > max_frame_size.height() || |
| 434 input_ratio > max_aspect_ratio || input_ratio < min_aspect_ratio) { |
| 435 int desired_width = std::min(max_frame_size.width(), input_size.width()); |
| 436 int desired_height = std::min(max_frame_size.height(), input_size.height()); |
| 437 |
| 438 const double resulting_ratio = |
| 439 static_cast<double>(desired_width) / desired_height; |
| 440 // Make sure |min_aspect_ratio| < |requested_ratio| < |max_aspect_ratio|. |
| 441 const double requested_ratio = |
| 442 std::max(std::min(resulting_ratio, max_aspect_ratio), min_aspect_ratio); |
| 443 |
| 444 if (resulting_ratio < requested_ratio) { |
| 445 desired_height = static_cast<int>((desired_height * resulting_ratio) / |
| 446 requested_ratio); |
| 447 // Make sure we scale to an even height to avoid rounding errors |
| 448 desired_height = (desired_height + 1) & ~1; |
| 449 } else if (resulting_ratio > requested_ratio) { |
| 450 desired_width = |
| 451 static_cast<int>((desired_width * requested_ratio) / resulting_ratio); |
| 452 // Make sure we scale to an even width to avoid rounding errors. |
| 453 desired_width = (desired_width + 1) & ~1; |
| 454 } |
| 455 |
| 456 *desired_size = gfx::Size(desired_width, desired_height); |
| 457 } else { |
| 458 *desired_size = input_size; |
| 459 } |
| 460 } |
| 461 |
| 451 void VideoTrackAdapter::StartFrameMonitoringOnIO( | 462 void VideoTrackAdapter::StartFrameMonitoringOnIO( |
| 452 const OnMutedCallback& on_muted_callback, | 463 const OnMutedCallback& on_muted_callback, |
| 453 double source_frame_rate) { | 464 double source_frame_rate) { |
| 454 DCHECK(io_task_runner_->BelongsToCurrentThread()); | 465 DCHECK(io_task_runner_->BelongsToCurrentThread()); |
| 455 DCHECK(!monitoring_frame_rate_); | 466 DCHECK(!monitoring_frame_rate_); |
| 456 | 467 |
| 457 monitoring_frame_rate_ = true; | 468 monitoring_frame_rate_ = true; |
| 458 | 469 |
| 459 // If the source does not know the frame rate, set one by default. | 470 // If the source does not know the frame rate, set one by default. |
| 460 if (source_frame_rate == 0.0f) | 471 if (source_frame_rate == 0.0f) |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 } | 525 } |
| 515 | 526 |
| 516 io_task_runner_->PostDelayedTask( | 527 io_task_runner_->PostDelayedTask( |
| 517 FROM_HERE, base::Bind(&VideoTrackAdapter::CheckFramesReceivedOnIO, this, | 528 FROM_HERE, base::Bind(&VideoTrackAdapter::CheckFramesReceivedOnIO, this, |
| 518 set_muted_state_callback, frame_counter_), | 529 set_muted_state_callback, frame_counter_), |
| 519 base::TimeDelta::FromSecondsD(kNormalFrameTimeoutInFrameIntervals / | 530 base::TimeDelta::FromSecondsD(kNormalFrameTimeoutInFrameIntervals / |
| 520 source_frame_rate_)); | 531 source_frame_rate_)); |
| 521 } | 532 } |
| 522 | 533 |
| 523 } // namespace content | 534 } // namespace content |
| OLD | NEW |