Reland "Add a high bitrate full stack test with fake codec"

In this reland, I disabled high bitrate webrtc perf test on Android32.

This is a reland of 15df2774f4e85cf8900768c1793edcf17d651dcd

Original change's description:
> This CL adds a fake codec factory  in WebRTC that can be used in tests to
> produce target bitrate output.

> We also add a high bitrate test that makes use of fake codec. This test assumes
> ideal network conditions with target bandwidth being available and exercises
> WebRTC calls with a high target bitrate(100 Mbps) end-to-end.

TBR=sprang@webrtc.org,stefan@webrtc.org,srte@webrtc.org,emircan@webrtc.org,kron@webrtc.org

Bug: chromium:879723
Change-Id: I31a4b48d986bef9ca003ae71afeb567ae3e562c9
Reviewed-on: https://webrtc-review.googlesource.com/c/117980
Reviewed-by: Emircan Uysaler <emircan@webrtc.org>
Commit-Queue: Emircan Uysaler <emircan@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26285}
This commit is contained in:
Emircan Uysaler 2019-01-16 15:07:56 -05:00 committed by Commit Bot
parent 52de8b0270
commit 7c03bdc1d3
9 changed files with 189 additions and 6 deletions

View File

@ -248,6 +248,8 @@ rtc_static_library("rtc_internal_video_codecs") {
"//third_party/abseil-cpp/absl/memory",
]
sources = [
"engine/fake_video_codec_factory.cc",
"engine/fake_video_codec_factory.h",
"engine/internal_decoder_factory.cc",
"engine/internal_decoder_factory.h",
"engine/internal_encoder_factory.cc",
@ -280,6 +282,7 @@ rtc_static_library("rtc_internal_video_codecs") {
"../api/video_codecs:video_codecs_api",
"../call:call_interfaces",
"../call:video_stream_api",
"../modules:module_api",
"../modules/video_coding:webrtc_h264",
"../modules/video_coding:webrtc_multiplex",
"../modules/video_coding:webrtc_vp8",
@ -288,6 +291,7 @@ rtc_static_library("rtc_internal_video_codecs") {
"../rtc_base:deprecation",
"../rtc_base:rtc_base_approved",
"../rtc_base/system:rtc_export",
"../test:fake_video_codecs",
"//third_party/abseil-cpp/absl/strings",
]
}

View File

@ -0,0 +1,76 @@
/*
* 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 "media/engine/fake_video_codec_factory.h"
#include "absl/memory/memory.h"
#include "api/video_codecs/sdp_video_format.h"
#include "api/video_codecs/video_decoder.h"
#include "api/video_codecs/video_encoder.h"
#include "modules/include/module_common_types.h"
#include "modules/video_coding/include/video_codec_interface.h"
#include "modules/video_coding/include/video_error_codes.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "test/fake_decoder.h"
#include "test/fake_encoder.h"
namespace {
static const char kFakeCodecFactoryCodecName[] = "FakeCodec";
} // anonymous namespace
namespace webrtc {
FakeVideoEncoderFactory::FakeVideoEncoderFactory() = default;
// static
std::unique_ptr<VideoEncoder> FakeVideoEncoderFactory::CreateVideoEncoder() {
return absl::make_unique<test::FakeEncoder>(Clock::GetRealTimeClock(),
10000000);
}
std::vector<SdpVideoFormat> FakeVideoEncoderFactory::GetSupportedFormats()
const {
return std::vector<SdpVideoFormat>(
1, SdpVideoFormat(kFakeCodecFactoryCodecName));
}
VideoEncoderFactory::CodecInfo FakeVideoEncoderFactory::QueryVideoEncoder(
const SdpVideoFormat& format) const {
return VideoEncoderFactory::CodecInfo{false, false};
}
std::unique_ptr<VideoEncoder> FakeVideoEncoderFactory::CreateVideoEncoder(
const SdpVideoFormat& format) {
return absl::make_unique<test::FakeEncoder>(Clock::GetRealTimeClock(),
10000000);
}
FakeVideoDecoderFactory::FakeVideoDecoderFactory() = default;
// static
std::unique_ptr<VideoDecoder> FakeVideoDecoderFactory::CreateVideoDecoder() {
return absl::make_unique<test::FakeDecoder>();
}
std::vector<SdpVideoFormat> FakeVideoDecoderFactory::GetSupportedFormats()
const {
return std::vector<SdpVideoFormat>(
1, SdpVideoFormat(kFakeCodecFactoryCodecName));
}
std::unique_ptr<VideoDecoder> FakeVideoDecoderFactory::CreateVideoDecoder(
const SdpVideoFormat& format) {
return absl::make_unique<test::FakeDecoder>();
}
} // namespace webrtc

View File

@ -0,0 +1,54 @@
/*
* 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.
*/
#ifndef MEDIA_ENGINE_FAKE_VIDEO_CODEC_FACTORY_H_
#define MEDIA_ENGINE_FAKE_VIDEO_CODEC_FACTORY_H_
#include <memory>
#include <vector>
#include "api/video_codecs/video_decoder_factory.h"
#include "api/video_codecs/video_encoder_factory.h"
namespace webrtc {
// Provides a fake video encoder instance that produces frames large enough for
// the given bitrate constraints.
class FakeVideoEncoderFactory : public VideoEncoderFactory {
public:
FakeVideoEncoderFactory();
static std::unique_ptr<VideoEncoder> CreateVideoEncoder();
// VideoEncoderFactory implementation
std::vector<SdpVideoFormat> GetSupportedFormats() const override;
VideoEncoderFactory::CodecInfo QueryVideoEncoder(
const SdpVideoFormat& format) const override;
std::unique_ptr<VideoEncoder> CreateVideoEncoder(
const SdpVideoFormat& format) override;
};
// Provides a fake video decoder instance that ignores the given bitstream and
// produces frames.
class FakeVideoDecoderFactory : public VideoDecoderFactory {
public:
FakeVideoDecoderFactory();
static std::unique_ptr<VideoDecoder> CreateVideoDecoder();
// VideoDecoderFactory implementation
std::vector<SdpVideoFormat> GetSupportedFormats() const override;
std::unique_ptr<VideoDecoder> CreateVideoDecoder(
const SdpVideoFormat& format) override;
};
} // namespace webrtc
#endif // MEDIA_ENGINE_FAKE_VIDEO_CODEC_FACTORY_H_

View File

@ -603,7 +603,7 @@ rtc_source_set("single_threaded_task_queue") {
}
rtc_source_set("fake_video_codecs") {
testonly = true
allow_poison = [ "software_video_codecs" ]
visibility = [ "*" ]
sources = [
"configurable_frame_size_encoder.cc",

View File

@ -47,7 +47,9 @@ void WriteCounter(unsigned char* payload, uint32_t counter) {
}; // namespace
FakeEncoder::FakeEncoder(Clock* clock)
FakeEncoder::FakeEncoder(Clock* clock) : FakeEncoder(clock, 100000) {}
FakeEncoder::FakeEncoder(Clock* clock, size_t buffer_size)
: clock_(clock),
callback_(nullptr),
configured_input_framerate_(-1),
@ -56,7 +58,8 @@ FakeEncoder::FakeEncoder(Clock* clock)
counter_(0),
debt_bytes_(0) {
// Generate some arbitrary not-all-zero data
for (size_t i = 0; i < sizeof(encoded_buffer_); ++i) {
encoded_buffer_.resize(buffer_size);
for (size_t i = 0; i < encoded_buffer_.size(); ++i) {
encoded_buffer_[i] = static_cast<uint8_t>(i);
}
for (bool& used : used_layers_) {
@ -130,12 +133,12 @@ int32_t FakeEncoder::Encode(const VideoFrame& input_image,
specifics.codecType = kVideoCodecGeneric;
std::unique_ptr<uint8_t[]> encoded_buffer(
new uint8_t[frame_info.layers[i].size]);
memcpy(encoded_buffer.get(), encoded_buffer_,
memcpy(encoded_buffer.get(), encoded_buffer_.data(),
frame_info.layers[i].size - 4);
// Write a counter to the image to make each frame unique.
WriteCounter(encoded_buffer.get() + frame_info.layers[i].size - 4, counter);
EncodedImage encoded(encoded_buffer.get(), frame_info.layers[i].size,
sizeof(encoded_buffer_));
encoded_buffer_.size());
encoded.SetTimestamp(input_image.timestamp());
encoded.capture_time_ms_ = input_image.render_time_ms();
encoded._frameType =

View File

@ -36,6 +36,7 @@ namespace test {
class FakeEncoder : public VideoEncoder {
public:
explicit FakeEncoder(Clock* clock);
FakeEncoder(Clock* clock, size_t buffer_size);
virtual ~FakeEncoder() = default;
// Sets max bitrate. Not thread-safe, call before registering the encoder.
@ -91,7 +92,7 @@ class FakeEncoder : public VideoEncoder {
uint32_t counter_ RTC_GUARDED_BY(crit_sect_);
rtc::CriticalSection crit_sect_;
uint8_t encoded_buffer_[100000];
std::vector<uint8_t> encoded_buffer_;
bool used_layers_[kMaxSimulcastStreams];
// Current byte debt to be payed over a number of frames.

View File

@ -262,6 +262,7 @@ if (rtc_include_tests) {
"../rtc_base:rtc_base_approved",
"../rtc_base:rtc_base_tests_utils",
"../system_wrappers",
"../test:fake_video_codecs",
"../test:fileutils",
"../test:perf_test",
"../test:rtp_test_utils",

View File

@ -1092,6 +1092,43 @@ TEST(FullStackTest, SimulcastVP8_3SL_Low) {
fixture->RunWithAnalyzer(simulcast);
}
// This test assumes ideal network conditions with target bandwidth being
// available and exercises WebRTC calls with a high target bitrate(100 Mbps).
// Android32 bots can't handle this high bitrate, so disable test for those.
#if defined(WEBRTC_ANDROID)
#define MAYBE_HighBitrateWithFakeCodec DISABLE_HighBitrateWithFakeCodec
#else
#define MAYBE_HighBitrateWithFakeCodec HighBitrateWithFakeCodec
#endif // defined(WEBRTC_ANDROID)
TEST(FullStackTest, MAYBE_HighBitrateWithFakeCodec) {
auto fixture = CreateVideoQualityTestFixture();
const int target_bitrate = 100000000;
ParamsWithLogging generator;
generator.call.send_side_bwe = true;
generator.call.call_bitrate_config.min_bitrate_bps = target_bitrate;
generator.call.call_bitrate_config.start_bitrate_bps = target_bitrate;
generator.call.call_bitrate_config.max_bitrate_bps = target_bitrate;
generator.video[0] = {true,
360,
240,
30,
target_bitrate / 2,
target_bitrate,
target_bitrate * 2,
false,
"FakeCodec",
1,
0,
0,
false,
false,
false,
"Generator"};
generator.analyzer = {"high_bitrate_with_fake_codec", 0.0, 0.0,
kFullStackTestDurationSecs};
fixture->RunWithAnalyzer(generator);
}
TEST(FullStackTest, LargeRoomVP8_5thumb) {
auto fixture = CreateVideoQualityTestFixture();
ParamsWithLogging large_room;

View File

@ -23,6 +23,7 @@
#include "logging/rtc_event_log/output/rtc_event_log_output_file.h"
#include "media/engine/adm_helpers.h"
#include "media/engine/encoder_simulcast_proxy.h"
#include "media/engine/fake_video_codec_factory.h"
#include "media/engine/internal_encoder_factory.h"
#include "media/engine/webrtc_video_engine.h"
#include "modules/audio_device/include/audio_device.h"
@ -170,6 +171,8 @@ std::unique_ptr<VideoDecoder> VideoQualityTest::CreateVideoDecoder(
if (format.name == "multiplex") {
decoder = absl::make_unique<MultiplexDecoderAdapter>(
&internal_decoder_factory_, SdpVideoFormat(cricket::kVp9CodecName));
} else if (format.name == "FakeCodec") {
decoder = webrtc::FakeVideoDecoderFactory::CreateVideoDecoder();
} else {
decoder = internal_decoder_factory_.CreateVideoDecoder(format);
}
@ -194,6 +197,8 @@ std::unique_ptr<VideoEncoder> VideoQualityTest::CreateVideoEncoder(
} else if (format.name == "multiplex") {
encoder = absl::make_unique<MultiplexEncoderAdapter>(
&internal_encoder_factory_, SdpVideoFormat(cricket::kVp9CodecName));
} else if (format.name == "FakeCodec") {
encoder = webrtc::FakeVideoEncoderFactory::CreateVideoEncoder();
} else {
encoder = internal_encoder_factory_.CreateVideoEncoder(format);
}
@ -556,6 +561,8 @@ void VideoQualityTest::SetupVideo(Transport* send_transport,
payload_type = kPayloadTypeVP9;
} else if (params_.video[video_idx].codec == "multiplex") {
payload_type = kPayloadTypeVP9;
} else if (params_.video[video_idx].codec == "FakeCodec") {
payload_type = kFakeVideoSendPayloadType;
} else {
RTC_NOTREACHED() << "Codec not supported!";
return;