Bug 1803530 - Follow resolution alignment in VideoStreamFactory. r=webrtc-reviewers,jib

Differential Revision: https://phabricator.services.mozilla.com/D163598
This commit is contained in:
Andreas Pehrson 2022-12-05 09:15:15 +00:00
parent 337a93d8bd
commit 064e2290af
3 changed files with 50 additions and 1 deletions

View File

@ -212,7 +212,8 @@ bool operator==(const rtc::VideoSinkWants& aThis,
// This would have to be expanded should we make use of more members of
// rtc::VideoSinkWants.
return aThis.max_pixel_count == aOther.max_pixel_count &&
aThis.max_framerate_fps == aOther.max_framerate_fps;
aThis.max_framerate_fps == aOther.max_framerate_fps &&
aThis.resolution_alignment == aOther.resolution_alignment;
}
// TODO: Make this a defaulted operator when we have c++20 (bug 1731036).

View File

@ -281,6 +281,10 @@ gfx::IntSize VideoStreamFactory::CalculateScaledResolution(
}
}
// Simplest possible adaptation to resolution alignment.
width -= width % mWants.resolution_alignment;
height -= height % mWants.resolution_alignment;
// Dont scale below our minimum value to prevent problems.
const int minSize = 1;
if (width < minSize || height < minSize) {

View File

@ -2050,6 +2050,50 @@ TEST_F(VideoConduitTest, TestVideoEncodeLargeScaleResolutionByStreamCreation) {
}
}
TEST_F(VideoConduitTest, TestVideoEncodeResolutionAlignment) {
UniquePtr<MockVideoSink> sink(new MockVideoSink());
for (const auto& scales : {std::vector{1U}, std::vector{1U, 9U}}) {
mControl.Update([&](auto& aControl) {
aControl.mTransmitting = true;
VideoCodecConfig codecConfig(120, "VP8", EncodingConstraints());
for (const auto& scale : scales) {
auto& encoding = codecConfig.mEncodings.emplace_back();
encoding.constraints.scaleDownBy = scale;
}
aControl.mVideoSendCodec = Some(codecConfig);
aControl.mVideoSendRtpRtcpConfig =
Some(RtpRtcpConfig(webrtc::RtcpMode::kCompound));
aControl.mLocalSsrcs = scales;
});
ASSERT_TRUE(Call()->mVideoSendEncoderConfig);
for (const auto& alignment : {2, 16, 39, 400, 1000}) {
// Test that requesting specific alignment always results in the expected
// number of layers and valid alignment.
rtc::VideoSinkWants wants;
wants.resolution_alignment = alignment;
mVideoConduit->AddOrUpdateSink(sink.get(), wants);
const std::vector<webrtc::VideoStream> videoStreams =
Call()->CreateEncoderStreams(640, 480);
ASSERT_EQ(videoStreams.size(), scales.size());
for (size_t i = 0; i < videoStreams.size(); ++i) {
// videoStreams is backwards
const auto& stream = videoStreams[videoStreams.size() - 1 - i];
const auto& scale = scales[i];
uint32_t expectation =
480 / scale < static_cast<uint32_t>(alignment) ? 1 : 0;
EXPECT_EQ(stream.width % alignment, expectation)
<< " for scale " << scale << " and alignment " << alignment;
EXPECT_EQ(stream.height % alignment, expectation);
}
}
}
mVideoConduit->RemoveSink(sink.get());
}
TEST_F(VideoConduitTest, TestSettingRtpRtcpRsize) {
mControl.Update([&](auto& aControl) {
VideoCodecConfig codecConfig(120, "VP8", EncodingConstraints());