| /* | |
| * Copyright (c) 2015 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 <stdio.h> | |
| #include <map> | |
| #include "gflags/gflags.h" | |
| #include "testing/gtest/include/gtest/gtest.h" | |
| #include "webrtc/test/field_trial.h" | |
| #include "webrtc/test/frame_generator.h" | |
| #include "webrtc/test/frame_generator_capturer.h" | |
| #include "webrtc/test/run_test.h" | |
| #include "webrtc/test/testsupport/fileutils.h" | |
| #include "webrtc/typedefs.h" | |
| #include "webrtc/video/loopback.h" | |
| #include "webrtc/video/video_send_stream.h" | |
| namespace webrtc { | |
| namespace flags { | |
| // Fixed for prerecorded screenshare content. | |
| size_t Width() { | |
| return 1850; | |
| } | |
| size_t Height() { | |
| return 1110; | |
| } | |
| DEFINE_int32(fps, 5, "Frames per second."); | |
| int Fps() { | |
| return static_cast<int>(FLAGS_fps); | |
| } | |
| DEFINE_int32(min_bitrate, 50, "Minimum video bitrate."); | |
| size_t MinBitrate() { | |
| return static_cast<size_t>(FLAGS_min_bitrate); | |
| } | |
| DEFINE_int32(tl0_bitrate, 200, "Temporal layer 0 target bitrate."); | |
| size_t StartBitrate() { | |
| return static_cast<size_t>(FLAGS_tl0_bitrate); | |
| } | |
| DEFINE_int32(tl1_bitrate, 2000, "Temporal layer 1 target bitrate."); | |
| size_t MaxBitrate() { | |
| return static_cast<size_t>(FLAGS_tl1_bitrate); | |
| } | |
| DEFINE_int32(min_transmit_bitrate, 400, "Min transmit bitrate incl. padding."); | |
| int MinTransmitBitrate() { | |
| return FLAGS_min_transmit_bitrate; | |
| } | |
| DEFINE_string(codec, "VP8", "Video codec to use."); | |
| std::string Codec() { | |
| return static_cast<std::string>(FLAGS_codec); | |
| } | |
| DEFINE_int32(loss_percent, 0, "Percentage of packets randomly lost."); | |
| int LossPercent() { | |
| return static_cast<int>(FLAGS_loss_percent); | |
| } | |
| DEFINE_int32(link_capacity, | |
| 0, | |
| "Capacity (kbps) of the fake link. 0 means infinite."); | |
| int LinkCapacity() { | |
| return static_cast<int>(FLAGS_link_capacity); | |
| } | |
| DEFINE_int32(queue_size, 0, "Size of the bottleneck link queue in packets."); | |
| int QueueSize() { | |
| return static_cast<int>(FLAGS_queue_size); | |
| } | |
| DEFINE_int32(avg_propagation_delay_ms, | |
| 0, | |
| "Average link propagation delay in ms."); | |
| int AvgPropagationDelayMs() { | |
| return static_cast<int>(FLAGS_avg_propagation_delay_ms); | |
| } | |
| DEFINE_int32(std_propagation_delay_ms, | |
| 0, | |
| "Link propagation delay standard deviation in ms."); | |
| int StdPropagationDelayMs() { | |
| return static_cast<int>(FLAGS_std_propagation_delay_ms); | |
| } | |
| DEFINE_bool(logs, false, "print logs to stderr"); | |
| DEFINE_string( | |
| force_fieldtrials, | |
| "", | |
| "Field trials control experimental feature code which can be forced. " | |
| "E.g. running with --force_fieldtrials=WebRTC-FooFeature/Enable/" | |
| " will assign the group Enable to field trial WebRTC-FooFeature. Multiple " | |
| "trials are separated by \"/\""); | |
| } // namespace flags | |
| class ScreenshareLoopback : public test::Loopback { | |
| public: | |
| explicit ScreenshareLoopback(const Config& config) : Loopback(config) { | |
| vp8_settings_ = VideoEncoder::GetDefaultVp8Settings(); | |
| vp8_settings_.denoisingOn = false; | |
| vp8_settings_.frameDroppingOn = false; | |
| vp8_settings_.numberOfTemporalLayers = 2; | |
| } | |
| virtual ~ScreenshareLoopback() {} | |
| protected: | |
| VideoEncoderConfig CreateEncoderConfig() override { | |
| VideoEncoderConfig encoder_config(test::Loopback::CreateEncoderConfig()); | |
| VideoStream* stream = &encoder_config.streams[0]; | |
| encoder_config.content_type = VideoEncoderConfig::ContentType::kScreen; | |
| encoder_config.min_transmit_bitrate_bps = flags::MinTransmitBitrate(); | |
| encoder_config.encoder_specific_settings = &vp8_settings_; | |
| stream->temporal_layer_thresholds_bps.clear(); | |
| stream->target_bitrate_bps = | |
| static_cast<int>(config_.start_bitrate_kbps) * 1000; | |
| stream->temporal_layer_thresholds_bps.push_back(stream->target_bitrate_bps); | |
| return encoder_config; | |
| } | |
| test::VideoCapturer* CreateCapturer(VideoSendStream* send_stream) override { | |
| std::vector<std::string> slides; | |
| slides.push_back(test::ResourcePath("web_screenshot_1850_1110", "yuv")); | |
| slides.push_back(test::ResourcePath("presentation_1850_1110", "yuv")); | |
| slides.push_back(test::ResourcePath("photo_1850_1110", "yuv")); | |
| slides.push_back(test::ResourcePath("difficult_photo_1850_1110", "yuv")); | |
| test::FrameGenerator* frame_generator = | |
| test::FrameGenerator::CreateFromYuvFile( | |
| slides, flags::Width(), flags::Height(), 10 * flags::Fps()); | |
| test::FrameGeneratorCapturer* capturer(new test::FrameGeneratorCapturer( | |
| clock_, send_stream->Input(), frame_generator, flags::Fps())); | |
| EXPECT_TRUE(capturer->Init()); | |
| return capturer; | |
| } | |
| VideoCodecVP8 vp8_settings_; | |
| }; | |
| void Loopback() { | |
| test::Loopback::Config config{flags::Width(), | |
| flags::Height(), | |
| flags::Fps(), | |
| flags::MinBitrate(), | |
| flags::StartBitrate(), | |
| flags::MaxBitrate(), | |
| flags::MinTransmitBitrate(), | |
| flags::Codec(), | |
| 0, // Default number of temporal layers. | |
| flags::LossPercent(), | |
| flags::LinkCapacity(), | |
| flags::QueueSize(), | |
| flags::AvgPropagationDelayMs(), | |
| flags::StdPropagationDelayMs(), | |
| flags::FLAGS_logs}; | |
| ScreenshareLoopback loopback(config); | |
| loopback.Run(); | |
| } | |
| } // namespace webrtc | |
| int main(int argc, char* argv[]) { | |
| ::testing::InitGoogleTest(&argc, argv); | |
| google::ParseCommandLineFlags(&argc, &argv, true); | |
| webrtc::test::InitFieldTrialsFromString( | |
| webrtc::flags::FLAGS_force_fieldtrials); | |
| webrtc::test::RunTest(webrtc::Loopback); | |
| return 0; | |
| } |