webrtc_m130/media/base/video_adapter.cc

495 lines
19 KiB
C++
Raw Permalink Normal View History

/*
* Copyright (c) 2010 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "media/base/video_adapter.h"
#include <algorithm>
#include <cmath>
#include <cstdint>
#include <cstdlib>
#include <limits>
#include <numeric>
#include <optional>
#include <string>
#include <utility>
#include "api/video/resolution.h"
#include "api/video/video_source_interface.h"
#include "media/base/video_common.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/strings/string_builder.h"
#include "rtc_base/synchronization/mutex.h"
#include "rtc_base/time_utils.h"
namespace {
struct Fraction {
int numerator;
int denominator;
void DivideByGcd() {
int g = std::gcd(numerator, denominator);
numerator /= g;
denominator /= g;
}
// Determines number of output pixels if both width and height of an input of
// `input_pixels` pixels is scaled with the fraction numerator / denominator.
int scale_pixel_count(int input_pixels) {
return (numerator * numerator * static_cast<int64_t>(input_pixels)) /
(denominator * denominator);
}
};
// Round `value_to_round` to a multiple of `multiple`. Prefer rounding upwards,
// but never more than `max_value`.
int roundUp(int value_to_round, int multiple, int max_value) {
const int rounded_value =
(value_to_round + multiple - 1) / multiple * multiple;
return rounded_value <= max_value ? rounded_value
: (max_value / multiple * multiple);
}
// Generates a scale factor that makes `input_pixels` close to `target_pixels`,
// but no higher than `max_pixels`.
Fraction FindScale(int input_width,
int input_height,
int target_pixels,
int max_pixels) {
// This function only makes sense for a positive target.
RTC_DCHECK_GT(target_pixels, 0);
RTC_DCHECK_GT(max_pixels, 0);
RTC_DCHECK_GE(max_pixels, target_pixels);
const int input_pixels = input_width * input_height;
// Don't scale up original.
if (target_pixels >= input_pixels)
return Fraction{1, 1};
Fraction current_scale = Fraction{1, 1};
Fraction best_scale = Fraction{1, 1};
// Start scaling down by 2/3 depending on `input_width` and `input_height`.
if (input_width % 3 == 0 && input_height % 3 == 0) {
// 2/3 (then alternates 3/4, 2/3, 3/4,...).
current_scale = Fraction{6, 6};
}
if (input_width % 9 == 0 && input_height % 9 == 0) {
// 2/3, 2/3 (then alternates 3/4, 2/3, 3/4,...).
current_scale = Fraction{36, 36};
}
// The minimum (absolute) difference between the number of output pixels and
// the target pixel count.
int min_pixel_diff = std::numeric_limits<int>::max();
if (input_pixels <= max_pixels) {
// Start condition for 1/1 case, if it is less than max.
min_pixel_diff = std::abs(input_pixels - target_pixels);
}
// Alternately scale down by 3/4 and 2/3. This results in fractions which are
// effectively scalable. For instance, starting at 1280x720 will result in
// the series (3/4) => 960x540, (1/2) => 640x360, (3/8) => 480x270,
// (1/4) => 320x180, (3/16) => 240x125, (1/8) => 160x90.
while (current_scale.scale_pixel_count(input_pixels) > target_pixels) {
if (current_scale.numerator % 3 == 0 &&
current_scale.denominator % 2 == 0) {
// Multiply by 2/3.
current_scale.numerator /= 3;
current_scale.denominator /= 2;
} else {
// Multiply by 3/4.
current_scale.numerator *= 3;
current_scale.denominator *= 4;
}
int output_pixels = current_scale.scale_pixel_count(input_pixels);
if (output_pixels <= max_pixels) {
int diff = std::abs(target_pixels - output_pixels);
if (diff < min_pixel_diff) {
min_pixel_diff = diff;
best_scale = current_scale;
}
}
}
best_scale.DivideByGcd();
return best_scale;
}
std::optional<std::pair<int, int>> Swap(
const std::optional<std::pair<int, int>>& in) {
if (!in) {
return std::nullopt;
}
return std::make_pair(in->second, in->first);
}
} // namespace
namespace cricket {
VideoAdapter::VideoAdapter(int source_resolution_alignment)
: frames_in_(0),
frames_out_(0),
frames_scaled_(0),
adaption_changes_(0),
previous_width_(0),
previous_height_(0),
source_resolution_alignment_(source_resolution_alignment),
resolution_alignment_(source_resolution_alignment),
resolution_request_target_pixel_count_(std::numeric_limits<int>::max()),
Reland of Add framerate to VideoSinkWants and ability to signal on overuse (patchset #1 id:1 of https://codereview.webrtc.org/2783183003/ ) Reason for revert: Seem to be a flaky test rather than an issue with this cl. Creating reland, will add code to reduce flakiness to that test. Original issue's description: > Revert of Add framerate to VideoSinkWants and ability to signal on overuse (patchset #8 id:410001 of https://codereview.webrtc.org/2781433002/ ) > > Reason for revert: > This has resulted in failure of CallPerfTest.ReceivesCpuOveruseAndUnderuse test on the Win7 build bot https://build.chromium.org/p/client.webrtc.perf/builders/Win7/builds/1780 > > Original issue's description: > > Reland of Add framerate to VideoSinkWants and ability to signal on overuse (patchset #1 id:1 of https://codereview.webrtc.org/2764133002/ ) > > > > Reason for revert: > > Found issue with test case, will add fix to reland cl. > > > > Original issue's description: > > > Revert of Add framerate to VideoSinkWants and ability to signal on overuse (patchset #14 id:250001 of https://codereview.webrtc.org/2716643002/ ) > > > > > > Reason for revert: > > > Breaks perf tests: > > > https://build.chromium.org/p/client.webrtc.perf/builders/Win7/builds/1679 > > > https://build.chromium.org/p/client.webrtc.perf/builders/Android32%20Tests%20%28L%20Nexus5%29/builds/2325 > > > > > > Original issue's description: > > > > Add framerate to VideoSinkWants and ability to signal on overuse > > > > > > > > In ViEEncoder, try to reduce framerate instead of resolution if the > > > > current degradation preference is maintain-resolution rather than > > > > balanced. > > > > > > > > BUG=webrtc:4172 > > > > > > > > Review-Url: https://codereview.webrtc.org/2716643002 > > > > Cr-Commit-Position: refs/heads/master@{#17327} > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/72acf2526177bb4dbb5103cd6e165eb4361a5ae6 > > > > > > TBR=nisse@webrtc.org,magjed@webrtc.org,kthelgason@webrtc.org,ilnik@webrtc.org,stefan@webrtc.org,sprang@webrtc.org > > > # Skipping CQ checks because original CL landed less than 1 days ago. > > > NOPRESUBMIT=true > > > NOTREECHECKS=true > > > NOTRY=true > > > BUG=webrtc:4172 > > > > > > Review-Url: https://codereview.webrtc.org/2764133002 > > > Cr-Commit-Position: refs/heads/master@{#17331} > > > Committed: https://chromium.googlesource.com/external/webrtc/+/8b45b11144c968b4173215c76f78c710c9a2ed0b > > > > TBR=nisse@webrtc.org,magjed@webrtc.org,kthelgason@webrtc.org,ilnik@webrtc.org,stefan@webrtc.org,skvlad@webrtc.org > > # Not skipping CQ checks because original CL landed more than 1 days ago. > > BUG=webrtc:4172 > > > > Review-Url: https://codereview.webrtc.org/2781433002 > > Cr-Commit-Position: refs/heads/master@{#17474} > > Committed: https://chromium.googlesource.com/external/webrtc/+/3ea3c77e93121b1ab9d5e46641e6764f2cca0d51 > > TBR=ilnik@webrtc.org,stefan@webrtc.org,asapersson@webrtc.org,sprang@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:4172 > > Review-Url: https://codereview.webrtc.org/2783183003 > Cr-Commit-Position: refs/heads/master@{#17477} > Committed: https://chromium.googlesource.com/external/webrtc/+/f9ed235c9b7248694edcb46feb1f29ce7456ab59 R=ilnik@webrtc.org,stefan@webrtc.org BUG=webrtc:4172 Review-Url: https://codereview.webrtc.org/2789823002 Cr-Commit-Position: refs/heads/master@{#17498}
2017-04-02 23:53:04 -07:00
resolution_request_max_pixel_count_(std::numeric_limits<int>::max()),
max_framerate_request_(std::numeric_limits<int>::max()) {}
VideoAdapter::VideoAdapter() : VideoAdapter(1) {}
VideoAdapter::~VideoAdapter() {}
bool VideoAdapter::DropFrame(int64_t in_timestamp_ns) {
int max_fps = max_framerate_request_;
if (output_format_request_.max_fps)
max_fps = std::min(max_fps, *output_format_request_.max_fps);
framerate_controller_.SetMaxFramerate(max_fps);
return framerate_controller_.ShouldDropFrame(in_timestamp_ns);
}
bool VideoAdapter::AdaptFrameResolution(int in_width,
int in_height,
int64_t in_timestamp_ns,
int* cropped_width,
int* cropped_height,
int* out_width,
int* out_height) {
webrtc::MutexLock lock(&mutex_);
++frames_in_;
// The max output pixel count is the minimum of the requests from
// OnOutputFormatRequest and OnResolutionFramerateRequest.
int max_pixel_count = resolution_request_max_pixel_count_;
// Select target aspect ratio and max pixel count depending on input frame
// orientation.
std::optional<std::pair<int, int>> target_aspect_ratio;
if (in_width > in_height) {
target_aspect_ratio = output_format_request_.target_landscape_aspect_ratio;
if (output_format_request_.max_landscape_pixel_count)
max_pixel_count = std::min(
max_pixel_count, *output_format_request_.max_landscape_pixel_count);
} else {
target_aspect_ratio = output_format_request_.target_portrait_aspect_ratio;
if (output_format_request_.max_portrait_pixel_count)
max_pixel_count = std::min(
max_pixel_count, *output_format_request_.max_portrait_pixel_count);
}
int target_pixel_count =
std::min(resolution_request_target_pixel_count_, max_pixel_count);
// Drop the input frame if necessary.
if (max_pixel_count <= 0 || DropFrame(in_timestamp_ns)) {
// Show VAdapt log every 90 frames dropped. (3 seconds)
if ((frames_in_ - frames_out_) % 90 == 0) {
// TODO(fbarchard): Reduce to LS_VERBOSE when adapter info is not needed
// in default calls.
RTC_LOG(LS_INFO) << "VAdapt Drop Frame: scaled " << frames_scaled_
<< " / out " << frames_out_ << " / in " << frames_in_
<< " Changes: " << adaption_changes_
<< " Input: " << in_width << "x" << in_height
<< " timestamp: " << in_timestamp_ns
<< " Output fps: " << max_framerate_request_ << "/"
<< output_format_request_.max_fps.value_or(-1)
<< " alignment: " << resolution_alignment_;
}
// Drop frame.
return false;
}
// Calculate how the input should be cropped.
if (!target_aspect_ratio || target_aspect_ratio->first <= 0 ||
target_aspect_ratio->second <= 0) {
*cropped_width = in_width;
*cropped_height = in_height;
} else {
const float requested_aspect =
target_aspect_ratio->first /
static_cast<float>(target_aspect_ratio->second);
*cropped_width =
std::min(in_width, static_cast<int>(in_height * requested_aspect));
*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);
// Adjust cropping slightly to get correctly aligned output size and a perfect
// scale factor.
*cropped_width = roundUp(*cropped_width,
scale.denominator * resolution_alignment_, in_width);
*cropped_height = roundUp(
*cropped_height, scale.denominator * resolution_alignment_, in_height);
RTC_DCHECK_EQ(0, *cropped_width % scale.denominator);
RTC_DCHECK_EQ(0, *cropped_height % scale.denominator);
// Calculate output size.
*out_width = *cropped_width / scale.denominator * scale.numerator;
*out_height = *cropped_height / scale.denominator * scale.numerator;
RTC_DCHECK_EQ(0, *out_width % resolution_alignment_);
RTC_DCHECK_EQ(0, *out_height % resolution_alignment_);
// Lastly, make the output size fit within the resolution restrictions as
Reland "Rename `requested_resolution` to `scale_resolution_down_to`." This is a reland of commit 82617ac51e7825db53451818f4d1ad52b69761fd The reason for the revert was a downstream use of `rtc::VideoSinkWants::requested_resolution`, so in this reland we don't rename this field, it's fine just to rename the one in RtpEncodingParameters for now. Original change's description: > Rename `requested_resolution` to `scale_resolution_down_to`. > > This is a pure refactor/rename CL without any changes in behavior. > > This field is called scaleResolutionDownTo in the spec and JavaScript. > Let's make C++ match to avoid confusion. > > In order not to break downstream during the transition a variable with > the old name being a pure reference to the renamed attribute is added. > This means we have to add custom constructors, but we can change this > back to "= default" when the transition is completed, which should only > be a couple of CLs away. > > Bug: webrtc:375048799 > Change-Id: If755102ccd79d46020ce5b33acd3dfcc29799e47 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366560 > Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> > Reviewed-by: Henrik Andreassson <henrika@webrtc.org> > Commit-Queue: Henrik Boström <hbos@webrtc.org> > Cr-Commit-Position: refs/heads/main@{#43300} NOTRY=True Bug: webrtc:375048799 Change-Id: Ic4ee156c1d50aa36070a8d84059870791dcbbe5e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366660 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Henrik Andreassson <henrika@webrtc.org> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43304}
2024-10-25 09:51:44 +02:00
// specified by `scale_resolution_down_to_`. This does not modify aspect ratio
// or cropping, only `out_width` and `out_height`.
if (scale_resolution_down_to_.has_value()) {
// Make frame and "scale to" have matching orientation.
webrtc::Resolution scale_resolution_down_to =
scale_resolution_down_to_.value();
if ((*out_width < *out_height) != (scale_resolution_down_to_->width <
scale_resolution_down_to_->height)) {
scale_resolution_down_to = {.width = scale_resolution_down_to_->height,
.height = scale_resolution_down_to_->width};
}
// Downscale by smallest scaling factor, if necessary.
if (*out_width > 0 && *out_height > 0 &&
Reland "Rename `requested_resolution` to `scale_resolution_down_to`." This is a reland of commit 82617ac51e7825db53451818f4d1ad52b69761fd The reason for the revert was a downstream use of `rtc::VideoSinkWants::requested_resolution`, so in this reland we don't rename this field, it's fine just to rename the one in RtpEncodingParameters for now. Original change's description: > Rename `requested_resolution` to `scale_resolution_down_to`. > > This is a pure refactor/rename CL without any changes in behavior. > > This field is called scaleResolutionDownTo in the spec and JavaScript. > Let's make C++ match to avoid confusion. > > In order not to break downstream during the transition a variable with > the old name being a pure reference to the renamed attribute is added. > This means we have to add custom constructors, but we can change this > back to "= default" when the transition is completed, which should only > be a couple of CLs away. > > Bug: webrtc:375048799 > Change-Id: If755102ccd79d46020ce5b33acd3dfcc29799e47 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366560 > Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> > Reviewed-by: Henrik Andreassson <henrika@webrtc.org> > Commit-Queue: Henrik Boström <hbos@webrtc.org> > Cr-Commit-Position: refs/heads/main@{#43300} NOTRY=True Bug: webrtc:375048799 Change-Id: Ic4ee156c1d50aa36070a8d84059870791dcbbe5e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366660 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Henrik Andreassson <henrika@webrtc.org> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43304}
2024-10-25 09:51:44 +02:00
(scale_resolution_down_to.width < *out_width ||
scale_resolution_down_to.height < *out_height)) {
double scale_factor = std::min(
Reland "Rename `requested_resolution` to `scale_resolution_down_to`." This is a reland of commit 82617ac51e7825db53451818f4d1ad52b69761fd The reason for the revert was a downstream use of `rtc::VideoSinkWants::requested_resolution`, so in this reland we don't rename this field, it's fine just to rename the one in RtpEncodingParameters for now. Original change's description: > Rename `requested_resolution` to `scale_resolution_down_to`. > > This is a pure refactor/rename CL without any changes in behavior. > > This field is called scaleResolutionDownTo in the spec and JavaScript. > Let's make C++ match to avoid confusion. > > In order not to break downstream during the transition a variable with > the old name being a pure reference to the renamed attribute is added. > This means we have to add custom constructors, but we can change this > back to "= default" when the transition is completed, which should only > be a couple of CLs away. > > Bug: webrtc:375048799 > Change-Id: If755102ccd79d46020ce5b33acd3dfcc29799e47 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366560 > Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> > Reviewed-by: Henrik Andreassson <henrika@webrtc.org> > Commit-Queue: Henrik Boström <hbos@webrtc.org> > Cr-Commit-Position: refs/heads/main@{#43300} NOTRY=True Bug: webrtc:375048799 Change-Id: Ic4ee156c1d50aa36070a8d84059870791dcbbe5e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366660 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Henrik Andreassson <henrika@webrtc.org> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43304}
2024-10-25 09:51:44 +02:00
scale_resolution_down_to.width / static_cast<double>(*out_width),
scale_resolution_down_to.height / static_cast<double>(*out_height));
*out_width =
roundUp(std::round(*out_width * scale_factor), resolution_alignment_,
scale_resolution_down_to.width);
*out_height =
roundUp(std::round(*out_height * scale_factor), resolution_alignment_,
scale_resolution_down_to.height);
RTC_DCHECK_EQ(0, *out_width % resolution_alignment_);
RTC_DCHECK_EQ(0, *out_height % resolution_alignment_);
}
}
++frames_out_;
if (scale.numerator != scale.denominator)
++frames_scaled_;
if (previous_width_ &&
(previous_width_ != *out_width || previous_height_ != *out_height)) {
++adaption_changes_;
RTC_LOG(LS_INFO) << "Frame size changed: scaled " << frames_scaled_
<< " / out " << frames_out_ << " / in " << frames_in_
<< " Changes: " << adaption_changes_
<< " Input: " << in_width << "x" << in_height
<< " Scale: " << scale.numerator << "/"
<< scale.denominator << " Output: " << *out_width << "x"
<< *out_height << " fps: " << max_framerate_request_ << "/"
<< output_format_request_.max_fps.value_or(-1)
<< " alignment: " << resolution_alignment_;
}
previous_width_ = *out_width;
previous_height_ = *out_height;
return true;
}
void VideoAdapter::OnOutputFormatRequest(
const std::optional<VideoFormat>& format) {
std::optional<std::pair<int, int>> target_aspect_ratio;
std::optional<int> max_pixel_count;
std::optional<int> max_fps;
if (format) {
target_aspect_ratio = std::make_pair(format->width, format->height);
max_pixel_count = format->width * format->height;
if (format->interval > 0)
max_fps = rtc::kNumNanosecsPerSec / format->interval;
}
OnOutputFormatRequest(target_aspect_ratio, max_pixel_count, max_fps);
}
void VideoAdapter::OnOutputFormatRequest(
const std::optional<std::pair<int, int>>& target_aspect_ratio,
const std::optional<int>& max_pixel_count,
const std::optional<int>& max_fps) {
std::optional<std::pair<int, int>> target_landscape_aspect_ratio;
std::optional<std::pair<int, int>> target_portrait_aspect_ratio;
if (target_aspect_ratio && target_aspect_ratio->first > 0 &&
target_aspect_ratio->second > 0) {
// Maintain input orientation.
const int max_side =
std::max(target_aspect_ratio->first, target_aspect_ratio->second);
const int min_side =
std::min(target_aspect_ratio->first, target_aspect_ratio->second);
target_landscape_aspect_ratio = std::make_pair(max_side, min_side);
target_portrait_aspect_ratio = std::make_pair(min_side, max_side);
}
OnOutputFormatRequest(target_landscape_aspect_ratio, max_pixel_count,
target_portrait_aspect_ratio, max_pixel_count, max_fps);
}
void VideoAdapter::OnOutputFormatRequest(
const std::optional<std::pair<int, int>>& target_landscape_aspect_ratio,
const std::optional<int>& max_landscape_pixel_count,
const std::optional<std::pair<int, int>>& target_portrait_aspect_ratio,
const std::optional<int>& max_portrait_pixel_count,
const std::optional<int>& max_fps) {
webrtc::MutexLock lock(&mutex_);
OutputFormatRequest request = {
.target_landscape_aspect_ratio = target_landscape_aspect_ratio,
.max_landscape_pixel_count = max_landscape_pixel_count,
.target_portrait_aspect_ratio = target_portrait_aspect_ratio,
.max_portrait_pixel_count = max_portrait_pixel_count,
.max_fps = max_fps};
if (stashed_output_format_request_) {
// Save the output format request for later use in case the encoder making
// this call would become active, because currently all active encoders use
Reland "Rename `requested_resolution` to `scale_resolution_down_to`." This is a reland of commit 82617ac51e7825db53451818f4d1ad52b69761fd The reason for the revert was a downstream use of `rtc::VideoSinkWants::requested_resolution`, so in this reland we don't rename this field, it's fine just to rename the one in RtpEncodingParameters for now. Original change's description: > Rename `requested_resolution` to `scale_resolution_down_to`. > > This is a pure refactor/rename CL without any changes in behavior. > > This field is called scaleResolutionDownTo in the spec and JavaScript. > Let's make C++ match to avoid confusion. > > In order not to break downstream during the transition a variable with > the old name being a pure reference to the renamed attribute is added. > This means we have to add custom constructors, but we can change this > back to "= default" when the transition is completed, which should only > be a couple of CLs away. > > Bug: webrtc:375048799 > Change-Id: If755102ccd79d46020ce5b33acd3dfcc29799e47 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366560 > Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> > Reviewed-by: Henrik Andreassson <henrika@webrtc.org> > Commit-Queue: Henrik Boström <hbos@webrtc.org> > Cr-Commit-Position: refs/heads/main@{#43300} NOTRY=True Bug: webrtc:375048799 Change-Id: Ic4ee156c1d50aa36070a8d84059870791dcbbe5e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366660 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Henrik Andreassson <henrika@webrtc.org> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43304}
2024-10-25 09:51:44 +02:00
// scale_resolution_down_to instead.
stashed_output_format_request_ = request;
RTC_LOG(LS_INFO) << "Stashing OnOutputFormatRequest: "
<< stashed_output_format_request_->ToString();
} else {
output_format_request_ = request;
RTC_LOG(LS_INFO) << "Setting output_format_request_: "
<< output_format_request_.ToString();
}
framerate_controller_.Reset();
}
void VideoAdapter::OnSinkWants(const rtc::VideoSinkWants& sink_wants) {
webrtc::MutexLock lock(&mutex_);
resolution_request_max_pixel_count_ = sink_wants.max_pixel_count;
resolution_request_target_pixel_count_ =
sink_wants.target_pixel_count.value_or(
resolution_request_max_pixel_count_);
max_framerate_request_ = sink_wants.max_framerate_fps;
resolution_alignment_ =
std::lcm(source_resolution_alignment_, sink_wants.resolution_alignment);
// Convert from std::optional<rtc::VideoSinkWants::FrameSize> to
// std::optional<webrtc::Resolution>. Both are {int,int}.
Reland "Rename `requested_resolution` to `scale_resolution_down_to`." This is a reland of commit 82617ac51e7825db53451818f4d1ad52b69761fd The reason for the revert was a downstream use of `rtc::VideoSinkWants::requested_resolution`, so in this reland we don't rename this field, it's fine just to rename the one in RtpEncodingParameters for now. Original change's description: > Rename `requested_resolution` to `scale_resolution_down_to`. > > This is a pure refactor/rename CL without any changes in behavior. > > This field is called scaleResolutionDownTo in the spec and JavaScript. > Let's make C++ match to avoid confusion. > > In order not to break downstream during the transition a variable with > the old name being a pure reference to the renamed attribute is added. > This means we have to add custom constructors, but we can change this > back to "= default" when the transition is completed, which should only > be a couple of CLs away. > > Bug: webrtc:375048799 > Change-Id: If755102ccd79d46020ce5b33acd3dfcc29799e47 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366560 > Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> > Reviewed-by: Henrik Andreassson <henrika@webrtc.org> > Commit-Queue: Henrik Boström <hbos@webrtc.org> > Cr-Commit-Position: refs/heads/main@{#43300} NOTRY=True Bug: webrtc:375048799 Change-Id: Ic4ee156c1d50aa36070a8d84059870791dcbbe5e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366660 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Henrik Andreassson <henrika@webrtc.org> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43304}
2024-10-25 09:51:44 +02:00
scale_resolution_down_to_ = std::nullopt;
Revert "Rename `requested_resolution` to `scale_resolution_down_to`." This reverts commit 82617ac51e7825db53451818f4d1ad52b69761fd. Reason for revert: Break downstream projects Original change's description: > Rename `requested_resolution` to `scale_resolution_down_to`. > > This is a pure refactor/rename CL without any changes in behavior. > > This field is called scaleResolutionDownTo in the spec and JavaScript. > Let's make C++ match to avoid confusion. > > In order not to break downstream during the transition a variable with > the old name being a pure reference to the renamed attribute is added. > This means we have to add custom constructors, but we can change this > back to "= default" when the transition is completed, which should only > be a couple of CLs away. > > Bug: webrtc:375048799 > Change-Id: If755102ccd79d46020ce5b33acd3dfcc29799e47 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366560 > Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> > Reviewed-by: Henrik Andreassson <henrika@webrtc.org> > Commit-Queue: Henrik Boström <hbos@webrtc.org> > Cr-Commit-Position: refs/heads/main@{#43300} Bug: webrtc:375048799 Change-Id: Ie41723a39420e12e7b5b681d3d00ccd14f66b4b1 No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366642 Reviewed-by: Harald Alvestrand <hta@webrtc.org> Commit-Queue: Florent Castelli <orphis@webrtc.org> Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com> Cr-Commit-Position: refs/heads/main@{#43301}
2024-10-24 14:36:27 +00:00
if (sink_wants.requested_resolution.has_value()) {
Reland "Rename `requested_resolution` to `scale_resolution_down_to`." This is a reland of commit 82617ac51e7825db53451818f4d1ad52b69761fd The reason for the revert was a downstream use of `rtc::VideoSinkWants::requested_resolution`, so in this reland we don't rename this field, it's fine just to rename the one in RtpEncodingParameters for now. Original change's description: > Rename `requested_resolution` to `scale_resolution_down_to`. > > This is a pure refactor/rename CL without any changes in behavior. > > This field is called scaleResolutionDownTo in the spec and JavaScript. > Let's make C++ match to avoid confusion. > > In order not to break downstream during the transition a variable with > the old name being a pure reference to the renamed attribute is added. > This means we have to add custom constructors, but we can change this > back to "= default" when the transition is completed, which should only > be a couple of CLs away. > > Bug: webrtc:375048799 > Change-Id: If755102ccd79d46020ce5b33acd3dfcc29799e47 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366560 > Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> > Reviewed-by: Henrik Andreassson <henrika@webrtc.org> > Commit-Queue: Henrik Boström <hbos@webrtc.org> > Cr-Commit-Position: refs/heads/main@{#43300} NOTRY=True Bug: webrtc:375048799 Change-Id: Ic4ee156c1d50aa36070a8d84059870791dcbbe5e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366660 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Henrik Andreassson <henrika@webrtc.org> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43304}
2024-10-25 09:51:44 +02:00
scale_resolution_down_to_ = {
.width = sink_wants.requested_resolution->width,
.height = sink_wants.requested_resolution->height};
}
Reland "Rename `requested_resolution` to `scale_resolution_down_to`." This is a reland of commit 82617ac51e7825db53451818f4d1ad52b69761fd The reason for the revert was a downstream use of `rtc::VideoSinkWants::requested_resolution`, so in this reland we don't rename this field, it's fine just to rename the one in RtpEncodingParameters for now. Original change's description: > Rename `requested_resolution` to `scale_resolution_down_to`. > > This is a pure refactor/rename CL without any changes in behavior. > > This field is called scaleResolutionDownTo in the spec and JavaScript. > Let's make C++ match to avoid confusion. > > In order not to break downstream during the transition a variable with > the old name being a pure reference to the renamed attribute is added. > This means we have to add custom constructors, but we can change this > back to "= default" when the transition is completed, which should only > be a couple of CLs away. > > Bug: webrtc:375048799 > Change-Id: If755102ccd79d46020ce5b33acd3dfcc29799e47 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366560 > Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> > Reviewed-by: Henrik Andreassson <henrika@webrtc.org> > Commit-Queue: Henrik Boström <hbos@webrtc.org> > Cr-Commit-Position: refs/heads/main@{#43300} NOTRY=True Bug: webrtc:375048799 Change-Id: Ic4ee156c1d50aa36070a8d84059870791dcbbe5e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366660 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Henrik Andreassson <henrika@webrtc.org> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43304}
2024-10-25 09:51:44 +02:00
// If scale_resolution_down_to is used, and there are no active encoders
// that are NOT using scale_resolution_down_to (aka newapi), then override
// calls to OnOutputFormatRequest and use values from scale_resolution_down_to
// instead (combined with qualityscaling based on pixel counts above).
Revert "Rename `requested_resolution` to `scale_resolution_down_to`." This reverts commit 82617ac51e7825db53451818f4d1ad52b69761fd. Reason for revert: Break downstream projects Original change's description: > Rename `requested_resolution` to `scale_resolution_down_to`. > > This is a pure refactor/rename CL without any changes in behavior. > > This field is called scaleResolutionDownTo in the spec and JavaScript. > Let's make C++ match to avoid confusion. > > In order not to break downstream during the transition a variable with > the old name being a pure reference to the renamed attribute is added. > This means we have to add custom constructors, but we can change this > back to "= default" when the transition is completed, which should only > be a couple of CLs away. > > Bug: webrtc:375048799 > Change-Id: If755102ccd79d46020ce5b33acd3dfcc29799e47 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366560 > Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> > Reviewed-by: Henrik Andreassson <henrika@webrtc.org> > Commit-Queue: Henrik Boström <hbos@webrtc.org> > Cr-Commit-Position: refs/heads/main@{#43300} Bug: webrtc:375048799 Change-Id: Ie41723a39420e12e7b5b681d3d00ccd14f66b4b1 No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366642 Reviewed-by: Harald Alvestrand <hta@webrtc.org> Commit-Queue: Florent Castelli <orphis@webrtc.org> Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com> Cr-Commit-Position: refs/heads/main@{#43301}
2024-10-24 14:36:27 +00:00
if (!sink_wants.requested_resolution) {
if (stashed_output_format_request_) {
// because current active_output_format_request is based on
Reland "Rename `requested_resolution` to `scale_resolution_down_to`." This is a reland of commit 82617ac51e7825db53451818f4d1ad52b69761fd The reason for the revert was a downstream use of `rtc::VideoSinkWants::requested_resolution`, so in this reland we don't rename this field, it's fine just to rename the one in RtpEncodingParameters for now. Original change's description: > Rename `requested_resolution` to `scale_resolution_down_to`. > > This is a pure refactor/rename CL without any changes in behavior. > > This field is called scaleResolutionDownTo in the spec and JavaScript. > Let's make C++ match to avoid confusion. > > In order not to break downstream during the transition a variable with > the old name being a pure reference to the renamed attribute is added. > This means we have to add custom constructors, but we can change this > back to "= default" when the transition is completed, which should only > be a couple of CLs away. > > Bug: webrtc:375048799 > Change-Id: If755102ccd79d46020ce5b33acd3dfcc29799e47 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366560 > Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> > Reviewed-by: Henrik Andreassson <henrika@webrtc.org> > Commit-Queue: Henrik Boström <hbos@webrtc.org> > Cr-Commit-Position: refs/heads/main@{#43300} NOTRY=True Bug: webrtc:375048799 Change-Id: Ic4ee156c1d50aa36070a8d84059870791dcbbe5e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366660 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Henrik Andreassson <henrika@webrtc.org> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43304}
2024-10-25 09:51:44 +02:00
// scale_resolution_down_to logic, while current encoder(s) doesn't want
// that, we have to restore the stashed request.
RTC_LOG(LS_INFO) << "Unstashing OnOutputFormatRequest: "
<< stashed_output_format_request_->ToString();
output_format_request_ = *stashed_output_format_request_;
stashed_output_format_request_.reset();
}
return;
}
Reland "Rename `requested_resolution` to `scale_resolution_down_to`." This is a reland of commit 82617ac51e7825db53451818f4d1ad52b69761fd The reason for the revert was a downstream use of `rtc::VideoSinkWants::requested_resolution`, so in this reland we don't rename this field, it's fine just to rename the one in RtpEncodingParameters for now. Original change's description: > Rename `requested_resolution` to `scale_resolution_down_to`. > > This is a pure refactor/rename CL without any changes in behavior. > > This field is called scaleResolutionDownTo in the spec and JavaScript. > Let's make C++ match to avoid confusion. > > In order not to break downstream during the transition a variable with > the old name being a pure reference to the renamed attribute is added. > This means we have to add custom constructors, but we can change this > back to "= default" when the transition is completed, which should only > be a couple of CLs away. > > Bug: webrtc:375048799 > Change-Id: If755102ccd79d46020ce5b33acd3dfcc29799e47 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366560 > Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> > Reviewed-by: Henrik Andreassson <henrika@webrtc.org> > Commit-Queue: Henrik Boström <hbos@webrtc.org> > Cr-Commit-Position: refs/heads/main@{#43300} NOTRY=True Bug: webrtc:375048799 Change-Id: Ic4ee156c1d50aa36070a8d84059870791dcbbe5e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366660 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Henrik Andreassson <henrika@webrtc.org> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43304}
2024-10-25 09:51:44 +02:00
// The code below is only needed when `scale_resolution_down_to` is signalled
// back to the video source which only happens if
// `VideoStreamEncoderSettings::use_standard_scale_resolution_down_to` is
// false.
Avoid signaling requested_resolution back to the adapting source. When requested_resolution uses a different aspect ratio than the source the encoder will restrict the frame without changing its aspect ratio, e.g. a 60x30 input frame that is restricted to 30x30 results in 30x15, not 30x30. While this logic works correctly in isolation, if the source also adapts the frame size based on the sink_wants.requested_resolution that is signaled back to the source, then the source will produce stretched 30x30 prior to the encoder which happily sends 30x30 not knowing any wiser. This is incompatible with the spec[1] and makes this WPT[2] fail. The correct behavior is to NOT signal the requested_resolution back to the source, the encoder already configures the correct resolution so this isn't actually needed and the source shouldn't need to know this API. In order not to break downstream projects, the new behavior is landed behind a flag and both behaviors are tested with TEST_P. This unblocks launching scaleResolutionDownTo API on Web. Migrating from old to new code path and deleting the flag is a follow-up AI: webrtc:366284861. [1] https://w3c.github.io/webrtc-extensions/#dom-rtcrtpencodingparameters-scaleresolutiondownto [2] https://chromium-review.googlesource.com/c/chromium/src/+/5853944 # Relying on previous green runs for confidence due to purple bots atm, # see b/367211396 NOTRY=True NOPRESUBMIT=True Bug: webrtc:366067962, webrtc:366284861 Change-Id: I7fd1016e9cc6f0b0b9b8c23b0708e521f8e12642 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/362541 Reviewed-by: Henrik Andreassson <henrika@webrtc.org> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Commit-Queue: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43024}
2024-09-16 12:57:42 +02:00
// TODO(https://crbug.com/webrtc/366284861): Delete the code below as part of
// deleting this flag and only supporting the standard behavior.
if (sink_wants.aggregates.has_value() &&
Revert "Rename `requested_resolution` to `scale_resolution_down_to`." This reverts commit 82617ac51e7825db53451818f4d1ad52b69761fd. Reason for revert: Break downstream projects Original change's description: > Rename `requested_resolution` to `scale_resolution_down_to`. > > This is a pure refactor/rename CL without any changes in behavior. > > This field is called scaleResolutionDownTo in the spec and JavaScript. > Let's make C++ match to avoid confusion. > > In order not to break downstream during the transition a variable with > the old name being a pure reference to the renamed attribute is added. > This means we have to add custom constructors, but we can change this > back to "= default" when the transition is completed, which should only > be a couple of CLs away. > > Bug: webrtc:375048799 > Change-Id: If755102ccd79d46020ce5b33acd3dfcc29799e47 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366560 > Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> > Reviewed-by: Henrik Andreassson <henrika@webrtc.org> > Commit-Queue: Henrik Boström <hbos@webrtc.org> > Cr-Commit-Position: refs/heads/main@{#43300} Bug: webrtc:375048799 Change-Id: Ie41723a39420e12e7b5b681d3d00ccd14f66b4b1 No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366642 Reviewed-by: Harald Alvestrand <hta@webrtc.org> Commit-Queue: Florent Castelli <orphis@webrtc.org> Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com> Cr-Commit-Position: refs/heads/main@{#43301}
2024-10-24 14:36:27 +00:00
sink_wants.aggregates->any_active_without_requested_resolution) {
return;
}
if (!stashed_output_format_request_) {
// The active output format request is about to be cleared due to
// request_resolution. We need to save it for later use in case the encoder
// which doesn't use request_resolution logic become active in the future.
stashed_output_format_request_ = output_format_request_;
RTC_LOG(LS_INFO) << "Stashing OnOutputFormatRequest: "
<< stashed_output_format_request_->ToString();
}
Reland "Rename `requested_resolution` to `scale_resolution_down_to`." This is a reland of commit 82617ac51e7825db53451818f4d1ad52b69761fd The reason for the revert was a downstream use of `rtc::VideoSinkWants::requested_resolution`, so in this reland we don't rename this field, it's fine just to rename the one in RtpEncodingParameters for now. Original change's description: > Rename `requested_resolution` to `scale_resolution_down_to`. > > This is a pure refactor/rename CL without any changes in behavior. > > This field is called scaleResolutionDownTo in the spec and JavaScript. > Let's make C++ match to avoid confusion. > > In order not to break downstream during the transition a variable with > the old name being a pure reference to the renamed attribute is added. > This means we have to add custom constructors, but we can change this > back to "= default" when the transition is completed, which should only > be a couple of CLs away. > > Bug: webrtc:375048799 > Change-Id: If755102ccd79d46020ce5b33acd3dfcc29799e47 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366560 > Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> > Reviewed-by: Henrik Andreassson <henrika@webrtc.org> > Commit-Queue: Henrik Boström <hbos@webrtc.org> > Cr-Commit-Position: refs/heads/main@{#43300} NOTRY=True Bug: webrtc:375048799 Change-Id: Ic4ee156c1d50aa36070a8d84059870791dcbbe5e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366660 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Henrik Andreassson <henrika@webrtc.org> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43304}
2024-10-25 09:51:44 +02:00
// Clear the output format request, `scale_resolution_down_to_` will be
// applied instead which happens inside AdaptFrameResolution().
output_format_request_ = {};
}
int VideoAdapter::GetTargetPixels() const {
webrtc::MutexLock lock(&mutex_);
return resolution_request_target_pixel_count_;
}
float VideoAdapter::GetMaxFramerate() const {
webrtc::MutexLock lock(&mutex_);
// Minimum of `output_format_request_.max_fps` and `max_framerate_request_` is
// used to throttle frame-rate.
int framerate =
std::min(max_framerate_request_,
output_format_request_.max_fps.value_or(max_framerate_request_));
if (framerate == std::numeric_limits<int>::max()) {
return std::numeric_limits<float>::infinity();
} else {
return max_framerate_request_;
}
}
std::string VideoAdapter::OutputFormatRequest::ToString() const {
rtc::StringBuilder oss;
oss << "[ ";
if (target_landscape_aspect_ratio == Swap(target_portrait_aspect_ratio) &&
max_landscape_pixel_count == max_portrait_pixel_count) {
if (target_landscape_aspect_ratio) {
oss << target_landscape_aspect_ratio->first << "x"
<< target_landscape_aspect_ratio->second;
} else {
oss << "unset-resolution";
}
if (max_landscape_pixel_count) {
oss << " max_pixel_count: " << *max_landscape_pixel_count;
}
} else {
oss << "[ landscape: ";
if (target_landscape_aspect_ratio) {
oss << target_landscape_aspect_ratio->first << "x"
<< target_landscape_aspect_ratio->second;
} else {
oss << "unset";
}
if (max_landscape_pixel_count) {
oss << " max_pixel_count: " << *max_landscape_pixel_count;
}
oss << " ] [ portrait: ";
if (target_portrait_aspect_ratio) {
oss << target_portrait_aspect_ratio->first << "x"
<< target_portrait_aspect_ratio->second;
}
if (max_portrait_pixel_count) {
oss << " max_pixel_count: " << *max_portrait_pixel_count;
}
oss << " ]";
}
oss << " max_fps: ";
if (max_fps) {
oss << *max_fps;
} else {
oss << "unset";
}
oss << " ]";
return oss.Release();
}
} // namespace cricket