Chromium Code Reviews| Index: webrtc/media/base/videoadapter.cc |
| diff --git a/webrtc/media/base/videoadapter.cc b/webrtc/media/base/videoadapter.cc |
| index 660df8ad673e8f40668d8f150722cb21082073ee..f84114c9c1a60809f03d8e041b3f24106c7930b2 100644 |
| --- a/webrtc/media/base/videoadapter.cc |
| +++ b/webrtc/media/base/videoadapter.cc |
| @@ -21,6 +21,7 @@ |
| #include "webrtc/base/optional.h" |
| #include "webrtc/media/base/mediaconstants.h" |
| #include "webrtc/media/base/videocommon.h" |
| +#include "webrtc/media/base/videosourceinterface.h" |
| namespace { |
| struct Fraction { |
| @@ -45,7 +46,10 @@ int roundUp(int value_to_round, int multiple, int max_value) { |
| // Generates a scale factor that makes |input_pixels| close to |target_pixels|, |
| // but no higher than |max_pixels|. |
| -Fraction FindScale(int input_pixels, int target_pixels, int max_pixels) { |
| +Fraction FindScale(int input_pixels, |
| + int target_pixels, |
| + int max_pixels, |
| + int min_pixels) { |
| // This function only makes sense for a positive target. |
| RTC_DCHECK_GT(target_pixels, 0); |
| RTC_DCHECK_GT(max_pixels, 0); |
| @@ -82,6 +86,10 @@ Fraction FindScale(int input_pixels, int target_pixels, int max_pixels) { |
| } |
| int output_pixels = current_scale.scale_pixel_count(input_pixels); |
| + if (output_pixels < min_pixels) { |
| + // Don't violate lower bound; |
| + break; |
| + } |
| if (output_pixels <= max_pixels) { |
| int diff = std::abs(target_pixels - output_pixels); |
| if (diff < min_pixel_diff) { |
| @@ -104,9 +112,7 @@ VideoAdapter::VideoAdapter(int required_resolution_alignment) |
| adaption_changes_(0), |
| previous_width_(0), |
| previous_height_(0), |
| - required_resolution_alignment_(required_resolution_alignment), |
| - resolution_request_target_pixel_count_(std::numeric_limits<int>::max()), |
| - resolution_request_max_pixel_count_(std::numeric_limits<int>::max()) {} |
| + required_resolution_alignment_(required_resolution_alignment) {} |
| VideoAdapter::VideoAdapter() : VideoAdapter(1) {} |
| @@ -114,21 +120,35 @@ VideoAdapter::~VideoAdapter() {} |
| bool VideoAdapter::KeepFrame(int64_t in_timestamp_ns) { |
| rtc::CritScope cs(&critical_section_); |
| - if (!requested_format_ || requested_format_->interval == 0) |
| + |
| + int64_t frame_interval_ns = 0; |
| + if (requested_format_ && requested_format_->interval) |
| + frame_interval_ns = requested_format_->interval; |
| + // TODO(sprang): Take target/min into consideration when implementing smoother |
| + // frame dropping. |
| + if (requested_sink_wants_.framerate_fps_) { |
| + frame_interval_ns = std::max<int64_t>( |
| + frame_interval_ns, |
| + rtc::kNumNanosecsPerSec / requested_sink_wants_.framerate_fps_->max); |
| + } |
| + |
| + if (frame_interval_ns <= 0) { |
| + // Frame rate throttling not enabled. |
| return true; |
| + } |
| if (next_frame_timestamp_ns_) { |
| // Time until next frame should be outputted. |
| const int64_t time_until_next_frame_ns = |
| (*next_frame_timestamp_ns_ - in_timestamp_ns); |
| - // Continue if timestamp is withing expected range. |
| - if (std::abs(time_until_next_frame_ns) < 2 * requested_format_->interval) { |
| + // Continue if timestamp is within expected range. |
| + if (std::abs(time_until_next_frame_ns) < 2 * frame_interval_ns) { |
| // Drop if a frame shouldn't be outputted yet. |
| if (time_until_next_frame_ns > 0) |
| return false; |
| // Time to output new frame. |
| - *next_frame_timestamp_ns_ += requested_format_->interval; |
| + *next_frame_timestamp_ns_ += frame_interval_ns; |
| return true; |
| } |
| } |
| @@ -137,7 +157,7 @@ bool VideoAdapter::KeepFrame(int64_t in_timestamp_ns) { |
| // reset. Set first timestamp target to just half the interval to prefer |
| // keeping frames in case of jitter. |
| next_frame_timestamp_ns_ = |
| - rtc::Optional<int64_t>(in_timestamp_ns + requested_format_->interval / 2); |
| + rtc::Optional<int64_t>(in_timestamp_ns + frame_interval_ns / 2); |
| return true; |
| } |
| @@ -153,13 +173,19 @@ bool VideoAdapter::AdaptFrameResolution(int in_width, |
| // The max output pixel count is the minimum of the requests from |
| // OnOutputFormatRequest and OnResolutionRequest. |
| - int max_pixel_count = resolution_request_max_pixel_count_; |
| + |
| + rtc::VideoSinkWants::ValueRange requested_range = |
| + requested_sink_wants_.pixel_count.value_or( |
| + rtc::VideoSinkWants::ValueRange()); |
| + RTC_DCHECK_GE(requested_range.target, requested_range.min); |
| + RTC_DCHECK_GE(requested_range.max, requested_range.target); |
| + uint32_t max_pixel_count = requested_range.max; |
| if (requested_format_) { |
| max_pixel_count = std::min( |
| - max_pixel_count, requested_format_->width * requested_format_->height); |
| + max_pixel_count, static_cast<uint32_t>(requested_format_->width * |
| + requested_format_->height)); |
| } |
| - int target_pixel_count = |
| - std::min(resolution_request_target_pixel_count_, max_pixel_count); |
| + int target_pixel_count = std::min(requested_range.target, max_pixel_count); |
| // Drop the input frame if necessary. |
| if (max_pixel_count <= 0 || !KeepFrame(in_timestamp_ns)) { |
| @@ -201,8 +227,9 @@ bool VideoAdapter::AdaptFrameResolution(int in_width, |
| *cropped_height = |
| std::min(in_height, static_cast<int>(in_width / requested_aspect)); |
| } |
| - const Fraction scale = FindScale((*cropped_width) * (*cropped_height), |
| - target_pixel_count, max_pixel_count); |
| + const Fraction scale = |
| + FindScale((*cropped_width) * (*cropped_height), target_pixel_count, |
| + max_pixel_count, requested_range.min); |
| // Adjust cropping slightly to get even integer output size and a perfect |
| // scale factor. Make sure the resulting dimensions are aligned correctly |
| // to be nice to hardware encoders. |
| @@ -249,14 +276,9 @@ void VideoAdapter::OnOutputFormatRequest(const VideoFormat& format) { |
| next_frame_timestamp_ns_ = rtc::Optional<int64_t>(); |
| } |
| -void VideoAdapter::OnResolutionRequest( |
| - const rtc::Optional<int>& target_pixel_count, |
| - const rtc::Optional<int>& max_pixel_count) { |
| +void VideoAdapter::OnSinkWantsUpdated(const rtc::VideoSinkWants& sink_wants) { |
|
nisse-webrtc
2017/02/17 08:55:21
I understand this change makes things look a littl
sprang_webrtc
2017/02/20 15:48:35
Fair enough. Just didn't want to pass along 6 opti
|
| rtc::CritScope cs(&critical_section_); |
| - resolution_request_max_pixel_count_ = |
| - max_pixel_count.value_or(std::numeric_limits<int>::max()); |
| - resolution_request_target_pixel_count_ = |
| - target_pixel_count.value_or(resolution_request_max_pixel_count_); |
| + requested_sink_wants_ = sink_wants; |
| } |
| } // namespace cricket |