
This reverts commit 948b7e37557af68b3bc9b81b29ae2daffb2784ad. Reason for revert: downstream project fixed. Original change's description: > Revert "Add initial support for RtpEncodingParameters max_framerate." > > This reverts commit ced5cfdb35a20c684df927eab37e16d35979555f. > > Reason for revert: Breaks downstream project. > > Original change's description: > > Add initial support for RtpEncodingParameters max_framerate. > > > > Add support to set the framerate to the maximum of |max_framerate|. > > Different framerates are currently not supported per stream for video. > > > > Bug: webrtc:9597 > > Change-Id: Ie326617b66bd97be387f809a7f82b97b8f3ff5fe > > Reviewed-on: https://webrtc-review.googlesource.com/92392 > > Reviewed-by: Sebastian Jansson <srte@webrtc.org> > > Reviewed-by: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Magnus Jedvert <magjed@webrtc.org> > > Reviewed-by: Steve Anton <steveanton@webrtc.org> > > Commit-Queue: Åsa Persson <asapersson@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#24270} > > TBR=steveanton@webrtc.org,magjed@webrtc.org,asapersson@webrtc.org,sprang@webrtc.org,srte@webrtc.org > > Change-Id: I508fe48e0c53996654f657357913ac307dc256bd > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: webrtc:9597 > Reviewed-on: https://webrtc-review.googlesource.com/94060 > Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org> > Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#24277} TBR=steveanton@webrtc.org,mbonadei@webrtc.org,magjed@webrtc.org,asapersson@webrtc.org,sprang@webrtc.org,srte@webrtc.org Bug: webrtc:9597 Change-Id: Ieed9d62787f3e9dcb439399bfe7529012292381e Reviewed-on: https://webrtc-review.googlesource.com/100080 Reviewed-by: Åsa Persson <asapersson@webrtc.org> Cr-Commit-Position: refs/heads/master@{#24720}
264 lines
9.8 KiB
C++
264 lines
9.8 KiB
C++
/*
|
|
* Copyright (c) 2018 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 <string>
|
|
|
|
#include "media/engine/internalencoderfactory.h"
|
|
#include "modules/video_coding/codecs/h264/include/h264.h"
|
|
#include "modules/video_coding/codecs/vp8/include/vp8.h"
|
|
#include "modules/video_coding/codecs/vp9/include/vp9.h"
|
|
#include "test/call_test.h"
|
|
#include "test/field_trial.h"
|
|
#include "test/frame_generator_capturer.h"
|
|
#include "test/function_video_encoder_factory.h"
|
|
|
|
namespace webrtc {
|
|
namespace {
|
|
constexpr int kWidth = 1280;
|
|
constexpr int kHeight = 720;
|
|
constexpr int kLowStartBps = 100000;
|
|
constexpr int kHighStartBps = 600000;
|
|
constexpr size_t kTimeoutMs = 10000; // Some tests are expected to time out.
|
|
|
|
void SetEncoderSpecific(VideoEncoderConfig* encoder_config,
|
|
VideoCodecType type,
|
|
bool automatic_resize,
|
|
bool frame_dropping) {
|
|
if (type == kVideoCodecVP8) {
|
|
VideoCodecVP8 vp8 = VideoEncoder::GetDefaultVp8Settings();
|
|
vp8.automaticResizeOn = automatic_resize;
|
|
vp8.frameDroppingOn = frame_dropping;
|
|
encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
|
|
VideoEncoderConfig::Vp8EncoderSpecificSettings>(vp8);
|
|
} else if (type == kVideoCodecVP9) {
|
|
VideoCodecVP9 vp9 = VideoEncoder::GetDefaultVp9Settings();
|
|
vp9.automaticResizeOn = automatic_resize;
|
|
vp9.frameDroppingOn = frame_dropping;
|
|
encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
|
|
VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9);
|
|
} else if (type == kVideoCodecH264) {
|
|
VideoCodecH264 h264 = VideoEncoder::GetDefaultH264Settings();
|
|
h264.frameDroppingOn = frame_dropping;
|
|
encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
|
|
VideoEncoderConfig::H264EncoderSpecificSettings>(h264);
|
|
}
|
|
}
|
|
} // namespace
|
|
|
|
class QualityScalingTest : public test::CallTest {
|
|
protected:
|
|
void RunTest(VideoEncoderFactory* encoder_factory,
|
|
const std::string& payload_name,
|
|
int start_bps,
|
|
bool automatic_resize,
|
|
bool frame_dropping,
|
|
bool expect_adaptation);
|
|
|
|
const std::string kPrefix = "WebRTC-Video-QualityScaling/Enabled-";
|
|
const std::string kEnd = ",0,0,0.9995,0.9999,1/";
|
|
};
|
|
|
|
void QualityScalingTest::RunTest(VideoEncoderFactory* encoder_factory,
|
|
const std::string& payload_name,
|
|
int start_bps,
|
|
bool automatic_resize,
|
|
bool frame_dropping,
|
|
bool expect_adaptation) {
|
|
class ScalingObserver
|
|
: public test::SendTest,
|
|
public test::FrameGeneratorCapturer::SinkWantsObserver {
|
|
public:
|
|
ScalingObserver(VideoEncoderFactory* encoder_factory,
|
|
const std::string& payload_name,
|
|
int start_bps,
|
|
bool automatic_resize,
|
|
bool frame_dropping,
|
|
bool expect_adaptation)
|
|
: SendTest(expect_adaptation ? kDefaultTimeoutMs : kTimeoutMs),
|
|
encoder_factory_(encoder_factory),
|
|
payload_name_(payload_name),
|
|
start_bps_(start_bps),
|
|
automatic_resize_(automatic_resize),
|
|
frame_dropping_(frame_dropping),
|
|
expect_adaptation_(expect_adaptation) {}
|
|
|
|
private:
|
|
void OnFrameGeneratorCapturerCreated(
|
|
test::FrameGeneratorCapturer* frame_generator_capturer) override {
|
|
frame_generator_capturer->SetSinkWantsObserver(this);
|
|
// Set initial resolution.
|
|
frame_generator_capturer->ChangeResolution(kWidth, kHeight);
|
|
}
|
|
|
|
// Called when FrameGeneratorCapturer::AddOrUpdateSink is called.
|
|
void OnSinkWantsChanged(rtc::VideoSinkInterface<VideoFrame>* sink,
|
|
const rtc::VideoSinkWants& wants) override {
|
|
if (wants.max_pixel_count < kWidth * kHeight)
|
|
observation_complete_.Set();
|
|
}
|
|
void ModifySenderCallConfig(Call::Config* config) override {
|
|
config->bitrate_config.start_bitrate_bps = start_bps_;
|
|
}
|
|
|
|
void ModifyVideoConfigs(
|
|
VideoSendStream::Config* send_config,
|
|
std::vector<VideoReceiveStream::Config>* receive_configs,
|
|
VideoEncoderConfig* encoder_config) override {
|
|
send_config->encoder_settings.encoder_factory = encoder_factory_;
|
|
send_config->rtp.payload_name = payload_name_;
|
|
send_config->rtp.payload_type = kVideoSendPayloadType;
|
|
const VideoCodecType codec_type = PayloadStringToCodecType(payload_name_);
|
|
encoder_config->codec_type = codec_type;
|
|
encoder_config->max_bitrate_bps = start_bps_;
|
|
SetEncoderSpecific(encoder_config, codec_type, automatic_resize_,
|
|
frame_dropping_);
|
|
}
|
|
|
|
void PerformTest() override {
|
|
EXPECT_EQ(expect_adaptation_, Wait())
|
|
<< "Timed out while waiting for a scale down.";
|
|
}
|
|
|
|
VideoEncoderFactory* const encoder_factory_;
|
|
const std::string payload_name_;
|
|
const int start_bps_;
|
|
const bool automatic_resize_;
|
|
const bool frame_dropping_;
|
|
const bool expect_adaptation_;
|
|
} test(encoder_factory, payload_name, start_bps, automatic_resize,
|
|
frame_dropping, expect_adaptation);
|
|
|
|
RunBaseTest(&test);
|
|
}
|
|
|
|
TEST_F(QualityScalingTest, AdaptsDownForHighQp_Vp8) {
|
|
// VP8 QP thresholds, low:1, high:1 -> high QP.
|
|
test::ScopedFieldTrials field_trials(kPrefix + "1,1,0,0,0,0" + kEnd);
|
|
|
|
// QualityScaler enabled.
|
|
const bool kAutomaticResize = true;
|
|
const bool kFrameDropping = true;
|
|
const bool kExpectAdapt = true;
|
|
|
|
test::FunctionVideoEncoderFactory encoder_factory(
|
|
[]() { return VP8Encoder::Create(); });
|
|
RunTest(&encoder_factory, "VP8", kHighStartBps, kAutomaticResize,
|
|
kFrameDropping, kExpectAdapt);
|
|
}
|
|
|
|
TEST_F(QualityScalingTest, NoAdaptDownForHighQpWithResizeOff_Vp8) {
|
|
// VP8 QP thresholds, low:1, high:1 -> high QP.
|
|
test::ScopedFieldTrials field_trials(kPrefix + "1,1,0,0,0,0" + kEnd);
|
|
|
|
// QualityScaler disabled.
|
|
const bool kAutomaticResize = false;
|
|
const bool kFrameDropping = true;
|
|
const bool kExpectAdapt = false;
|
|
|
|
test::FunctionVideoEncoderFactory encoder_factory(
|
|
[]() { return VP8Encoder::Create(); });
|
|
RunTest(&encoder_factory, "VP8", kHighStartBps, kAutomaticResize,
|
|
kFrameDropping, kExpectAdapt);
|
|
}
|
|
|
|
TEST_F(QualityScalingTest, NoAdaptDownForHighQpWithFrameDroppingOff_Vp8) {
|
|
// VP8 QP thresholds, low:1, high:1 -> high QP.
|
|
test::ScopedFieldTrials field_trials(kPrefix + "1,1,0,0,0,0" + kEnd);
|
|
|
|
// QualityScaler disabled.
|
|
const bool kAutomaticResize = true;
|
|
const bool kFrameDropping = false;
|
|
const bool kExpectAdapt = false;
|
|
|
|
test::FunctionVideoEncoderFactory encoder_factory(
|
|
[]() { return VP8Encoder::Create(); });
|
|
RunTest(&encoder_factory, "VP8", kHighStartBps, kAutomaticResize,
|
|
kFrameDropping, kExpectAdapt);
|
|
}
|
|
|
|
TEST_F(QualityScalingTest, NoAdaptDownForNormalQp_Vp8) {
|
|
// VP8 QP thresholds, low:1, high:127 -> normal QP.
|
|
test::ScopedFieldTrials field_trials(kPrefix + "1,127,0,0,0,0" + kEnd);
|
|
|
|
// QualityScaler enabled.
|
|
const bool kAutomaticResize = true;
|
|
const bool kFrameDropping = true;
|
|
const bool kExpectAdapt = false;
|
|
|
|
test::FunctionVideoEncoderFactory encoder_factory(
|
|
[]() { return VP8Encoder::Create(); });
|
|
RunTest(&encoder_factory, "VP8", kHighStartBps, kAutomaticResize,
|
|
kFrameDropping, kExpectAdapt);
|
|
}
|
|
|
|
TEST_F(QualityScalingTest, AdaptsDownForLowStartBitrate) {
|
|
// VP8 QP thresholds, low:1, high:127 -> normal QP.
|
|
test::ScopedFieldTrials field_trials(kPrefix + "1,127,0,0,0,0" + kEnd);
|
|
|
|
// QualityScaler enabled.
|
|
const bool kAutomaticResize = true;
|
|
const bool kFrameDropping = true;
|
|
const bool kExpectAdapt = true;
|
|
|
|
test::FunctionVideoEncoderFactory encoder_factory(
|
|
[]() { return VP8Encoder::Create(); });
|
|
RunTest(&encoder_factory, "VP8", kLowStartBps, kAutomaticResize,
|
|
kFrameDropping, kExpectAdapt);
|
|
}
|
|
|
|
TEST_F(QualityScalingTest, NoAdaptDownForLowStartBitrateWithScalingOff) {
|
|
// VP8 QP thresholds, low:1, high:127 -> normal QP.
|
|
test::ScopedFieldTrials field_trials(kPrefix + "1,127,0,0,0,0" + kEnd);
|
|
|
|
// QualityScaler disabled.
|
|
const bool kAutomaticResize = false;
|
|
const bool kFrameDropping = true;
|
|
const bool kExpectAdapt = false;
|
|
|
|
test::FunctionVideoEncoderFactory encoder_factory(
|
|
[]() { return VP8Encoder::Create(); });
|
|
RunTest(&encoder_factory, "VP8", kLowStartBps, kAutomaticResize,
|
|
kFrameDropping, kExpectAdapt);
|
|
}
|
|
|
|
TEST_F(QualityScalingTest, NoAdaptDownForHighQp_Vp9) {
|
|
// VP9 QP thresholds, low:1, high:1 -> high QP.
|
|
test::ScopedFieldTrials field_trials(kPrefix + "0,0,1,1,0,0" + kEnd);
|
|
|
|
// QualityScaler always disabled.
|
|
const bool kAutomaticResize = true;
|
|
const bool kFrameDropping = true;
|
|
const bool kExpectAdapt = false;
|
|
|
|
test::FunctionVideoEncoderFactory encoder_factory(
|
|
[]() { return VP9Encoder::Create(); });
|
|
RunTest(&encoder_factory, "VP9", kHighStartBps, kAutomaticResize,
|
|
kFrameDropping, kExpectAdapt);
|
|
}
|
|
|
|
#if defined(WEBRTC_USE_H264)
|
|
TEST_F(QualityScalingTest, AdaptsDownForHighQp_H264) {
|
|
// H264 QP thresholds, low:1, high:1 -> high QP.
|
|
test::ScopedFieldTrials field_trials(kPrefix + "0,0,0,0,1,1" + kEnd);
|
|
|
|
// QualityScaler always enabled.
|
|
const bool kAutomaticResize = false;
|
|
const bool kFrameDropping = false;
|
|
const bool kExpectAdapt = true;
|
|
|
|
test::FunctionVideoEncoderFactory encoder_factory(
|
|
[]() { return H264Encoder::Create(cricket::VideoCodec("H264")); });
|
|
RunTest(&encoder_factory, "H264", kHighStartBps, kAutomaticResize,
|
|
kFrameDropping, kExpectAdapt);
|
|
}
|
|
#endif // defined(WEBRTC_USE_H264)
|
|
|
|
} // namespace webrtc
|