/* * Copyright 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 "video/end_to_end_tests/multi_stream_tester.h" #include #include #include #include "absl/memory/memory.h" #include "api/rtc_event_log/rtc_event_log.h" #include "api/task_queue/default_task_queue_factory.h" #include "api/task_queue/task_queue_base.h" #include "api/test/create_frame_generator.h" #include "api/test/simulated_network.h" #include "api/test/video/function_video_encoder_factory.h" #include "api/video/builtin_video_bitrate_allocator_factory.h" #include "call/fake_network_pipe.h" #include "call/simulated_network.h" #include "media/engine/internal_decoder_factory.h" #include "modules/video_coding/codecs/vp8/include/vp8.h" #include "rtc_base/task_queue_for_test.h" #include "test/call_test.h" #include "test/encoder_settings.h" namespace webrtc { MultiStreamTester::MultiStreamTester() { // TODO(sprang): Cleanup when msvc supports explicit initializers for array. codec_settings[0] = {1, 640, 480}; codec_settings[1] = {2, 320, 240}; codec_settings[2] = {3, 240, 160}; } MultiStreamTester::~MultiStreamTester() = default; void MultiStreamTester::RunTest() { webrtc::RtcEventLogNull event_log; auto task_queue_factory = CreateDefaultTaskQueueFactory(); // Use high prioirity since this task_queue used for fake network delivering // at correct time. Those test tasks should be prefered over code under test // to make test more stable. auto task_queue = task_queue_factory->CreateTaskQueue( "TaskQueue", TaskQueueFactory::Priority::HIGH); Call::Config config(&event_log); test::ScopedKeyValueConfig field_trials; config.trials = &field_trials; config.task_queue_factory = task_queue_factory.get(); std::unique_ptr sender_call; std::unique_ptr receiver_call; std::unique_ptr sender_transport; std::unique_ptr receiver_transport; VideoSendStream* send_streams[kNumStreams]; VideoReceiveStreamInterface* receive_streams[kNumStreams]; test::FrameGeneratorCapturer* frame_generators[kNumStreams]; test::FunctionVideoEncoderFactory encoder_factory( []() { return VP8Encoder::Create(); }); std::unique_ptr bitrate_allocator_factory = CreateBuiltinVideoBitrateAllocatorFactory(); InternalDecoderFactory decoder_factory; SendTask(task_queue.get(), [&]() { sender_call = absl::WrapUnique(Call::Create(config)); receiver_call = absl::WrapUnique(Call::Create(config)); sender_transport = CreateSendTransport(task_queue.get(), sender_call.get()); receiver_transport = CreateReceiveTransport(task_queue.get(), receiver_call.get()); sender_transport->SetReceiver(receiver_call->Receiver()); receiver_transport->SetReceiver(sender_call->Receiver()); for (size_t i = 0; i < kNumStreams; ++i) { uint32_t ssrc = codec_settings[i].ssrc; int width = codec_settings[i].width; int height = codec_settings[i].height; VideoSendStream::Config send_config(sender_transport.get()); send_config.rtp.ssrcs.push_back(ssrc); send_config.encoder_settings.encoder_factory = &encoder_factory; send_config.encoder_settings.bitrate_allocator_factory = bitrate_allocator_factory.get(); send_config.rtp.payload_name = "VP8"; send_config.rtp.payload_type = kVideoPayloadType; VideoEncoderConfig encoder_config; test::FillEncoderConfiguration(kVideoCodecVP8, 1, &encoder_config); encoder_config.max_bitrate_bps = 100000; UpdateSendConfig(i, &send_config, &encoder_config, &frame_generators[i]); send_streams[i] = sender_call->CreateVideoSendStream( send_config.Copy(), encoder_config.Copy()); send_streams[i]->Start(); VideoReceiveStreamInterface::Config receive_config( receiver_transport.get()); receive_config.rtp.remote_ssrc = ssrc; receive_config.rtp.local_ssrc = test::CallTest::kReceiverLocalVideoSsrc; receive_config.decoder_factory = &decoder_factory; VideoReceiveStreamInterface::Decoder decoder = test::CreateMatchingDecoder(send_config); receive_config.decoders.push_back(decoder); UpdateReceiveConfig(i, &receive_config); receive_streams[i] = receiver_call->CreateVideoReceiveStream(std::move(receive_config)); receive_streams[i]->Start(); auto* frame_generator = new test::FrameGeneratorCapturer( Clock::GetRealTimeClock(), test::CreateSquareFrameGenerator(width, height, absl::nullopt, absl::nullopt), 30, *task_queue_factory); frame_generators[i] = frame_generator; send_streams[i]->SetSource(frame_generator, DegradationPreference::MAINTAIN_FRAMERATE); frame_generator->Init(); frame_generator->Start(); } }); Wait(); SendTask(task_queue.get(), [&]() { for (size_t i = 0; i < kNumStreams; ++i) { frame_generators[i]->Stop(); sender_call->DestroyVideoSendStream(send_streams[i]); receiver_call->DestroyVideoReceiveStream(receive_streams[i]); delete frame_generators[i]; } sender_transport.reset(); receiver_transport.reset(); sender_call.reset(); receiver_call.reset(); }); } void MultiStreamTester::UpdateSendConfig( size_t stream_index, VideoSendStream::Config* send_config, VideoEncoderConfig* encoder_config, test::FrameGeneratorCapturer** frame_generator) {} void MultiStreamTester::UpdateReceiveConfig( size_t stream_index, VideoReceiveStreamInterface::Config* receive_config) {} std::unique_ptr MultiStreamTester::CreateSendTransport( TaskQueueBase* task_queue, Call* sender_call) { std::vector extensions = {}; return std::make_unique( task_queue, std::make_unique( Clock::GetRealTimeClock(), std::make_unique(BuiltInNetworkBehaviorConfig())), sender_call, payload_type_map_, extensions, extensions); } std::unique_ptr MultiStreamTester::CreateReceiveTransport(TaskQueueBase* task_queue, Call* receiver_call) { std::vector extensions = {}; return std::make_unique( task_queue, std::make_unique( Clock::GetRealTimeClock(), std::make_unique(BuiltInNetworkBehaviorConfig())), receiver_call, payload_type_map_, extensions, extensions); } } // namespace webrtc