| /* | |
| * 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 API_TEST_PEERCONNECTION_QUALITY_TEST_FIXTURE_H_ | |
| #define API_TEST_PEERCONNECTION_QUALITY_TEST_FIXTURE_H_ | |
| #include <map> | |
| #include <memory> | |
| #include <string> | |
| #include <utility> | |
| #include <vector> | |
| #include "absl/memory/memory.h" | |
| #include "absl/strings/string_view.h" | |
| #include "absl/types/optional.h" | |
| #include "api/array_view.h" | |
| #include "api/async_resolver_factory.h" | |
| #include "api/audio/audio_mixer.h" | |
| #include "api/call/call_factory_interface.h" | |
| #include "api/fec_controller.h" | |
| #include "api/function_view.h" | |
| #include "api/media_stream_interface.h" | |
| #include "api/peer_connection_interface.h" | |
| #include "api/rtc_event_log/rtc_event_log_factory_interface.h" | |
| #include "api/rtp_parameters.h" | |
| #include "api/task_queue/task_queue_factory.h" | |
| #include "api/test/audio_quality_analyzer_interface.h" | |
| #include "api/test/frame_generator_interface.h" | |
| #include "api/test/peer_network_dependencies.h" | |
| #include "api/test/simulated_network.h" | |
| #include "api/test/stats_observer_interface.h" | |
| #include "api/test/track_id_stream_info_map.h" | |
| #include "api/test/video_quality_analyzer_interface.h" | |
| #include "api/transport/network_control.h" | |
| #include "api/units/time_delta.h" | |
| #include "api/video_codecs/video_decoder_factory.h" | |
| #include "api/video_codecs/video_encoder.h" | |
| #include "api/video_codecs/video_encoder_factory.h" | |
| #include "media/base/media_constants.h" | |
| #include "modules/audio_processing/include/audio_processing.h" | |
| #include "rtc_base/network.h" | |
| #include "rtc_base/rtc_certificate_generator.h" | |
| #include "rtc_base/ssl_certificate.h" | |
| #include "rtc_base/thread.h" | |
| namespace webrtc { | |
| namespace webrtc_pc_e2e { | |
| constexpr size_t kDefaultSlidesWidth = 1850; | |
| constexpr size_t kDefaultSlidesHeight = 1110; | |
| // API is in development. Can be changed/removed without notice. | |
| class PeerConnectionE2EQualityTestFixture { | |
| public: | |
| // The index of required capturing device in OS provided list of video | |
| // devices. On Linux and Windows the list will be obtained via | |
| // webrtc::VideoCaptureModule::DeviceInfo, on Mac OS via | |
| // [RTCCameraVideoCapturer captureDevices]. | |
| enum class CapturingDeviceIndex : size_t {}; | |
| // Contains parameters for screen share scrolling. | |
| // | |
| // If scrolling is enabled, then it will be done by putting sliding window | |
| // on source video and moving this window from top left corner to the | |
| // bottom right corner of the picture. | |
| // | |
| // In such case source dimensions must be greater or equal to the sliding | |
| // window dimensions. So `source_width` and `source_height` are the dimensions | |
| // of the source frame, while `VideoConfig::width` and `VideoConfig::height` | |
| // are the dimensions of the sliding window. | |
| // | |
| // Because `source_width` and `source_height` are dimensions of the source | |
| // frame, they have to be width and height of videos from | |
| // `ScreenShareConfig::slides_yuv_file_names`. | |
| // | |
| // Because scrolling have to be done on single slide it also requires, that | |
| // `duration` must be less or equal to | |
| // `ScreenShareConfig::slide_change_interval`. | |
| struct ScrollingParams { | |
| ScrollingParams(TimeDelta duration, | |
| size_t source_width, | |
| size_t source_height) | |
| : duration(duration), | |
| source_width(source_width), | |
| source_height(source_height) { | |
| RTC_CHECK_GT(duration.ms(), 0); | |
| } | |
| // Duration of scrolling. | |
| TimeDelta duration; | |
| // Width of source slides video. | |
| size_t source_width; | |
| // Height of source slides video. | |
| size_t source_height; | |
| }; | |
| // Contains screen share video stream properties. | |
| struct ScreenShareConfig { | |
| explicit ScreenShareConfig(TimeDelta slide_change_interval) | |
| : slide_change_interval(slide_change_interval) { | |
| RTC_CHECK_GT(slide_change_interval.ms(), 0); | |
| } | |
| // Shows how long one slide should be presented on the screen during | |
| // slide generation. | |
| TimeDelta slide_change_interval; | |
| // If true, slides will be generated programmatically. No scrolling params | |
| // will be applied in such case. | |
| bool generate_slides = false; | |
| // If present scrolling will be applied. Please read extra requirement on | |
| // `slides_yuv_file_names` for scrolling. | |
| absl::optional<ScrollingParams> scrolling_params; | |
| // Contains list of yuv files with slides. | |
| // | |
| // If empty, default set of slides will be used. In such case | |
| // `VideoConfig::width` must be equal to `kDefaultSlidesWidth` and | |
| // `VideoConfig::height` must be equal to `kDefaultSlidesHeight` or if | |
| // `scrolling_params` are specified, then `ScrollingParams::source_width` | |
| // must be equal to `kDefaultSlidesWidth` and | |
| // `ScrollingParams::source_height` must be equal to `kDefaultSlidesHeight`. | |
| std::vector<std::string> slides_yuv_file_names; | |
| }; | |
| // Config for Vp8 simulcast or non-standard Vp9 SVC testing. | |
| // | |
| // To configure standard SVC setting, use `scalability_mode` in the | |
| // `encoding_params` array. | |
| // This configures Vp9 SVC by requesting simulcast layers, the request is | |
| // internally converted to a request for SVC layers. | |
| // | |
| // SVC support is limited: | |
| // During SVC testing there is no SFU, so framework will try to emulate SFU | |
| // behavior in regular p2p call. Because of it there are such limitations: | |
| // * if `target_spatial_index` is not equal to the highest spatial layer | |
| // then no packet/frame drops are allowed. | |
| // | |
| // If there will be any drops, that will affect requested layer, then | |
| // WebRTC SVC implementation will continue decoding only the highest | |
| // available layer and won't restore lower layers, so analyzer won't | |
| // receive required data which will cause wrong results or test failures. | |
| struct VideoSimulcastConfig { | |
| explicit VideoSimulcastConfig(int simulcast_streams_count) | |
| : simulcast_streams_count(simulcast_streams_count) { | |
| RTC_CHECK_GT(simulcast_streams_count, 1); | |
| } | |
| VideoSimulcastConfig(int simulcast_streams_count, int target_spatial_index) | |
| : simulcast_streams_count(simulcast_streams_count), | |
| target_spatial_index(target_spatial_index) { | |
| RTC_CHECK_GT(simulcast_streams_count, 1); | |
| RTC_CHECK_GE(target_spatial_index, 0); | |
| RTC_CHECK_LT(target_spatial_index, simulcast_streams_count); | |
| } | |
| // Specified amount of simulcast streams/SVC layers, depending on which | |
| // encoder is used. | |
| int simulcast_streams_count; | |
| // Specifies spatial index of the video stream to analyze. | |
| // There are 2 cases: | |
| // 1. simulcast encoder is used: | |
| // in such case `target_spatial_index` will specify the index of | |
| // simulcast stream, that should be analyzed. Other streams will be | |
| // dropped. | |
| // 2. SVC encoder is used: | |
| // in such case `target_spatial_index` will specify the top interesting | |
| // spatial layer and all layers below, including target one will be | |
| // processed. All layers above target one will be dropped. | |
| // If not specified than whatever stream will be received will be analyzed. | |
| // It requires Selective Forwarding Unit (SFU) to be configured in the | |
| // network. | |
| absl::optional<int> target_spatial_index; | |
| }; | |
| class VideoResolution { | |
| public: | |
| // Determines special resolutions, which can't be expressed in terms of | |
| // width, height and fps. | |
| enum class Spec { | |
| // No extra spec set. It describes a regular resolution described by | |
| // width, height and fps. | |
| kNone, | |
| // Describes resolution which contains max value among all sender's | |
| // video streams in each dimension (width, height, fps). | |
| kMaxFromSender | |
| }; | |
| VideoResolution(size_t width, size_t height, int32_t fps); | |
| explicit VideoResolution(Spec spec = Spec::kNone); | |
| bool operator==(const VideoResolution& other) const; | |
| bool operator!=(const VideoResolution& other) const { | |
| return !(*this == other); | |
| } | |
| size_t width() const { return width_; } | |
| void set_width(size_t width) { width_ = width; } | |
| size_t height() const { return height_; } | |
| void set_height(size_t height) { height_ = height; } | |
| int32_t fps() const { return fps_; } | |
| void set_fps(int32_t fps) { fps_ = fps; } | |
| // Returns if it is a regular resolution or not. The resolution is regular | |
| // if it's spec is `Spec::kNone`. | |
| bool IsRegular() const { return spec_ == Spec::kNone; } | |
| private: | |
| size_t width_ = 0; | |
| size_t height_ = 0; | |
| int32_t fps_ = 0; | |
| Spec spec_ = Spec::kNone; | |
| }; | |
| // Contains properties of single video stream. | |
| struct VideoConfig { | |
| explicit VideoConfig(const VideoResolution& resolution); | |
| VideoConfig(size_t width, size_t height, int32_t fps) | |
| : width(width), height(height), fps(fps) {} | |
| VideoConfig(std::string stream_label, | |
| size_t width, | |
| size_t height, | |
| int32_t fps) | |
| : width(width), | |
| height(height), | |
| fps(fps), | |
| stream_label(std::move(stream_label)) {} | |
| // Video stream width. | |
| size_t width; | |
| // Video stream height. | |
| size_t height; | |
| int32_t fps; | |
| VideoResolution GetResolution() const { | |
| return VideoResolution(width, height, fps); | |
| } | |
| // Have to be unique among all specified configs for all peers in the call. | |
| // Will be auto generated if omitted. | |
| absl::optional<std::string> stream_label; | |
| // Will be set for current video track. If equals to kText or kDetailed - | |
| // screencast in on. | |
| absl::optional<VideoTrackInterface::ContentHint> content_hint; | |
| // If presented video will be transfered in simulcast/SVC mode depending on | |
| // which encoder is used. | |
| // | |
| // Simulcast is supported only from 1st added peer. For VP8 simulcast only | |
| // without RTX is supported so it will be automatically disabled for all | |
| // simulcast tracks. For VP9 simulcast enables VP9 SVC mode and support RTX, | |
| // but only on non-lossy networks. See more in documentation to | |
| // VideoSimulcastConfig. | |
| absl::optional<VideoSimulcastConfig> simulcast_config; | |
| // Encoding parameters for both singlecast and per simulcast layer. | |
| // If singlecast is used, if not empty, a single value can be provided. | |
| // If simulcast is used, if not empty, `encoding_params` size have to be | |
| // equal to `simulcast_config.simulcast_streams_count`. Will be used to set | |
| // transceiver send encoding params for each layer. | |
| // RtpEncodingParameters::rid may be changed by fixture implementation to | |
| // ensure signaling correctness. | |
| std::vector<RtpEncodingParameters> encoding_params; | |
| // Count of temporal layers for video stream. This value will be set into | |
| // each RtpEncodingParameters of RtpParameters of corresponding | |
| // RtpSenderInterface for this video stream. | |
| absl::optional<int> temporal_layers_count; | |
| // If specified the input stream will be also copied to specified file. | |
| // It is actually one of the test's output file, which contains copy of what | |
| // was captured during the test for this video stream on sender side. | |
| // It is useful when generator is used as input. | |
| absl::optional<std::string> input_dump_file_name; | |
| // Used only if `input_dump_file_name` is set. Specifies the module for the | |
| // video frames to be dumped. Modulo equals X means every Xth frame will be | |
| // written to the dump file. The value must be greater than 0. | |
| int input_dump_sampling_modulo = 1; | |
| // If specified this file will be used as output on the receiver side for | |
| // this stream. | |
| // | |
| // If multiple output streams will be produced by this stream (e.g. when the | |
| // stream represented by this `VideoConfig` is received by more than one | |
| // peer), output files will be appended with receiver names. If the second | |
| // and other receivers will be added in the middle of the call after the | |
| // first frame for this stream has been already written to the output file, | |
| // then only dumps for newly added peers will be appended with receiver | |
| // name, the dump for the first receiver will have name equal to the | |
| // specified one. For example: | |
| // * If we have peers A and B and A has `VideoConfig` V_a with | |
| // V_a.output_dump_file_name = "/foo/a_output.yuv", then the stream | |
| // related to V_a will be written into "/foo/a_output.yuv". | |
| // * If we have peers A, B and C and A has `VideoConfig` V_a with | |
| // V_a.output_dump_file_name = "/foo/a_output.yuv", then the stream | |
| // related to V_a will be written for peer B into "/foo/a_output.yuv.B" | |
| // and for peer C into "/foo/a_output.yuv.C" | |
| // * If we have peers A and B and A has `VideoConfig` V_a with | |
| // V_a.output_dump_file_name = "/foo/a_output.yuv", then if after B | |
| // received the first frame related to V_a peer C joined the call, then | |
| // the stream related to V_a will be written for peer B into | |
| // "/foo/a_output.yuv" and for peer C into "/foo/a_output.yuv.C" | |
| // | |
| // The produced files contains what was rendered for this video stream on | |
| // receiver side. | |
| absl::optional<std::string> output_dump_file_name; | |
| // Used only if `output_dump_file_name` is set. Specifies the module for the | |
| // video frames to be dumped. Modulo equals X means every Xth frame will be | |
| // written to the dump file. The value must be greater than 0. | |
| int output_dump_sampling_modulo = 1; | |
| // If true will display input and output video on the user's screen. | |
| bool show_on_screen = false; | |
| // If specified, determines a sync group to which this video stream belongs. | |
| // According to bugs.webrtc.org/4762 WebRTC supports synchronization only | |
| // for pair of single audio and single video stream. | |
| absl::optional<std::string> sync_group; | |
| }; | |
| // Contains properties for audio in the call. | |
| struct AudioConfig { | |
| enum Mode { | |
| kGenerated, | |
| kFile, | |
| }; | |
| AudioConfig() = default; | |
| explicit AudioConfig(std::string stream_label) | |
| : stream_label(std::move(stream_label)) {} | |
| // Have to be unique among all specified configs for all peers in the call. | |
| // Will be auto generated if omitted. | |
| absl::optional<std::string> stream_label; | |
| Mode mode = kGenerated; | |
| // Have to be specified only if mode = kFile | |
| absl::optional<std::string> input_file_name; | |
| // If specified the input stream will be also copied to specified file. | |
| absl::optional<std::string> input_dump_file_name; | |
| // If specified the output stream will be copied to specified file. | |
| absl::optional<std::string> output_dump_file_name; | |
| // Audio options to use. | |
| cricket::AudioOptions audio_options; | |
| // Sampling frequency of input audio data (from file or generated). | |
| int sampling_frequency_in_hz = 48000; | |
| // If specified, determines a sync group to which this audio stream belongs. | |
| // According to bugs.webrtc.org/4762 WebRTC supports synchronization only | |
| // for pair of single audio and single video stream. | |
| absl::optional<std::string> sync_group; | |
| }; | |
| struct VideoCodecConfig { | |
| explicit VideoCodecConfig(std::string name) | |
| : name(std::move(name)), required_params() {} | |
| VideoCodecConfig(std::string name, | |
| std::map<std::string, std::string> required_params) | |
| : name(std::move(name)), required_params(std::move(required_params)) {} | |
| // Next two fields are used to specify concrete video codec, that should be | |
| // used in the test. Video code will be negotiated in SDP during offer/ | |
| // answer exchange. | |
| // Video codec name. You can find valid names in | |
| // media/base/media_constants.h | |
| std::string name = cricket::kVp8CodecName; | |
| // Map of parameters, that have to be specified on SDP codec. Each parameter | |
| // is described by key and value. Codec parameters will match the specified | |
| // map if and only if for each key from `required_params` there will be | |
| // a parameter with name equal to this key and parameter value will be equal | |
| // to the value from `required_params` for this key. | |
| // If empty then only name will be used to match the codec. | |
| std::map<std::string, std::string> required_params; | |
| }; | |
| // Subscription to the remote video streams. It declares which remote stream | |
| // peer should receive and in which resolution (width x height x fps). | |
| class VideoSubscription { | |
| public: | |
| // Returns the resolution constructed as maximum from all resolution | |
| // dimensions: width, height and fps. | |
| static absl::optional<VideoResolution> GetMaxResolution( | |
| rtc::ArrayView<const VideoConfig> video_configs); | |
| static absl::optional<VideoResolution> GetMaxResolution( | |
| rtc::ArrayView<const VideoResolution> resolutions); | |
| // Subscribes receiver to all streams sent by the specified peer with | |
| // specified resolution. It will override any resolution that was used in | |
| // `SubscribeToAll` independently from methods call order. | |
| VideoSubscription& SubscribeToPeer( | |
| absl::string_view peer_name, | |
| VideoResolution resolution = | |
| VideoResolution(VideoResolution::Spec::kMaxFromSender)) { | |
| peers_resolution_[std::string(peer_name)] = resolution; | |
| return *this; | |
| } | |
| // Subscribes receiver to the all sent streams with specified resolution. | |
| // If any stream was subscribed to with `SubscribeTo` method that will | |
| // override resolution passed to this function independently from methods | |
| // call order. | |
| VideoSubscription& SubscribeToAllPeers( | |
| VideoResolution resolution = | |
| VideoResolution(VideoResolution::Spec::kMaxFromSender)) { | |
| default_resolution_ = resolution; | |
| return *this; | |
| } | |
| // Returns resolution for specific sender. If no specific resolution was | |
| // set for this sender, then will return resolution used for all streams. | |
| // If subscription doesn't subscribe to all streams, `absl::nullopt` will be | |
| // returned. | |
| absl::optional<VideoResolution> GetResolutionForPeer( | |
| absl::string_view peer_name) const { | |
| auto it = peers_resolution_.find(std::string(peer_name)); | |
| if (it == peers_resolution_.end()) { | |
| return default_resolution_; | |
| } | |
| return it->second; | |
| } | |
| // Returns a maybe empty list of senders for which peer explicitly | |
| // subscribed to with specific resolution. | |
| std::vector<std::string> GetSubscribedPeers() const { | |
| std::vector<std::string> subscribed_streams; | |
| subscribed_streams.reserve(peers_resolution_.size()); | |
| for (const auto& entry : peers_resolution_) { | |
| subscribed_streams.push_back(entry.first); | |
| } | |
| return subscribed_streams; | |
| } | |
| private: | |
| absl::optional<VideoResolution> default_resolution_ = absl::nullopt; | |
| std::map<std::string, VideoResolution> peers_resolution_; | |
| }; | |
| // This class is used to fully configure one peer inside the call. | |
| class PeerConfigurer { | |
| public: | |
| virtual ~PeerConfigurer() = default; | |
| // Sets peer name that will be used to report metrics related to this peer. | |
| // If not set, some default name will be assigned. All names have to be | |
| // unique. | |
| virtual PeerConfigurer* SetName(absl::string_view name) = 0; | |
| // The parameters of the following 9 methods will be passed to the | |
| // PeerConnectionFactoryInterface implementation that will be created for | |
| // this peer. | |
| virtual PeerConfigurer* SetTaskQueueFactory( | |
| std::unique_ptr<TaskQueueFactory> task_queue_factory) = 0; | |
| virtual PeerConfigurer* SetCallFactory( | |
| std::unique_ptr<CallFactoryInterface> call_factory) = 0; | |
| virtual PeerConfigurer* SetEventLogFactory( | |
| std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory) = 0; | |
| virtual PeerConfigurer* SetFecControllerFactory( | |
| std::unique_ptr<FecControllerFactoryInterface> | |
| fec_controller_factory) = 0; | |
| virtual PeerConfigurer* SetNetworkControllerFactory( | |
| std::unique_ptr<NetworkControllerFactoryInterface> | |
| network_controller_factory) = 0; | |
| virtual PeerConfigurer* SetVideoEncoderFactory( | |
| std::unique_ptr<VideoEncoderFactory> video_encoder_factory) = 0; | |
| virtual PeerConfigurer* SetVideoDecoderFactory( | |
| std::unique_ptr<VideoDecoderFactory> video_decoder_factory) = 0; | |
| // Set a custom NetEqFactory to be used in the call. | |
| virtual PeerConfigurer* SetNetEqFactory( | |
| std::unique_ptr<NetEqFactory> neteq_factory) = 0; | |
| virtual PeerConfigurer* SetAudioProcessing( | |
| rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) = 0; | |
| virtual PeerConfigurer* SetAudioMixer( | |
| rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) = 0; | |
| // The parameters of the following 4 methods will be passed to the | |
| // PeerConnectionInterface implementation that will be created for this | |
| // peer. | |
| virtual PeerConfigurer* SetAsyncResolverFactory( | |
| std::unique_ptr<webrtc::AsyncResolverFactory> | |
| async_resolver_factory) = 0; | |
| virtual PeerConfigurer* SetRTCCertificateGenerator( | |
| std::unique_ptr<rtc::RTCCertificateGeneratorInterface> | |
| cert_generator) = 0; | |
| virtual PeerConfigurer* SetSSLCertificateVerifier( | |
| std::unique_ptr<rtc::SSLCertificateVerifier> tls_cert_verifier) = 0; | |
| virtual PeerConfigurer* SetIceTransportFactory( | |
| std::unique_ptr<IceTransportFactory> factory) = 0; | |
| // Flags to set on `cricket::PortAllocator`. These flags will be added | |
| // to the default ones that are presented on the port allocator. | |
| // For possible values check p2p/base/port_allocator.h. | |
| virtual PeerConfigurer* SetPortAllocatorExtraFlags( | |
| uint32_t extra_flags) = 0; | |
| // Add new video stream to the call that will be sent from this peer. | |
| // Default implementation of video frames generator will be used. | |
| virtual PeerConfigurer* AddVideoConfig(VideoConfig config) = 0; | |
| // Add new video stream to the call that will be sent from this peer with | |
| // provided own implementation of video frames generator. | |
| virtual PeerConfigurer* AddVideoConfig( | |
| VideoConfig config, | |
| std::unique_ptr<test::FrameGeneratorInterface> generator) = 0; | |
| // Add new video stream to the call that will be sent from this peer. | |
| // Capturing device with specified index will be used to get input video. | |
| virtual PeerConfigurer* AddVideoConfig( | |
| VideoConfig config, | |
| CapturingDeviceIndex capturing_device_index) = 0; | |
| // Sets video subscription for the peer. By default subscription will | |
| // include all streams with `VideoSubscription::kSameAsSendStream` | |
| // resolution. To override this behavior use this method. | |
| virtual PeerConfigurer* SetVideoSubscription( | |
| VideoSubscription subscription) = 0; | |
| // Set the list of video codecs used by the peer during the test. These | |
| // codecs will be negotiated in SDP during offer/answer exchange. The order | |
| // of these codecs during negotiation will be the same as in `video_codecs`. | |
| // Codecs have to be available in codecs list provided by peer connection to | |
| // be negotiated. If some of specified codecs won't be found, the test will | |
| // crash. | |
| virtual PeerConfigurer* SetVideoCodecs( | |
| std::vector<VideoCodecConfig> video_codecs) = 0; | |
| // Set the audio stream for the call from this peer. If this method won't | |
| // be invoked, this peer will send no audio. | |
| virtual PeerConfigurer* SetAudioConfig(AudioConfig config) = 0; | |
| // Set if ULP FEC should be used or not. False by default. | |
| virtual PeerConfigurer* SetUseUlpFEC(bool value) = 0; | |
| // Set if Flex FEC should be used or not. False by default. | |
| // Client also must enable `enable_flex_fec_support` in the `RunParams` to | |
| // be able to use this feature. | |
| virtual PeerConfigurer* SetUseFlexFEC(bool value) = 0; | |
| // Specifies how much video encoder target bitrate should be different than | |
| // target bitrate, provided by WebRTC stack. Must be greater than 0. Can be | |
| // used to emulate overshooting of video encoders. This multiplier will | |
| // be applied for all video encoder on both sides for all layers. Bitrate | |
| // estimated by WebRTC stack will be multiplied by this multiplier and then | |
| // provided into VideoEncoder::SetRates(...). 1.0 by default. | |
| virtual PeerConfigurer* SetVideoEncoderBitrateMultiplier( | |
| double multiplier) = 0; | |
| // If is set, an RTCEventLog will be saved in that location and it will be | |
| // available for further analysis. | |
| virtual PeerConfigurer* SetRtcEventLogPath(std::string path) = 0; | |
| // If is set, an AEC dump will be saved in that location and it will be | |
| // available for further analysis. | |
| virtual PeerConfigurer* SetAecDumpPath(std::string path) = 0; | |
| virtual PeerConfigurer* SetRTCConfiguration( | |
| PeerConnectionInterface::RTCConfiguration configuration) = 0; | |
| virtual PeerConfigurer* SetRTCOfferAnswerOptions( | |
| PeerConnectionInterface::RTCOfferAnswerOptions options) = 0; | |
| // Set bitrate parameters on PeerConnection. This constraints will be | |
| // applied to all summed RTP streams for this peer. | |
| virtual PeerConfigurer* SetBitrateSettings( | |
| BitrateSettings bitrate_settings) = 0; | |
| }; | |
| // Contains configuration for echo emulator. | |
| struct EchoEmulationConfig { | |
| // Delay which represents the echo path delay, i.e. how soon rendered signal | |
| // should reach capturer. | |
| TimeDelta echo_delay = TimeDelta::Millis(50); | |
| }; | |
| // Contains parameters, that describe how long framework should run quality | |
| // test. | |
| struct RunParams { | |
| explicit RunParams(TimeDelta run_duration) : run_duration(run_duration) {} | |
| // Specifies how long the test should be run. This time shows how long | |
| // the media should flow after connection was established and before | |
| // it will be shut downed. | |
| TimeDelta run_duration; | |
| // If set to true peers will be able to use Flex FEC, otherwise they won't | |
| // be able to negotiate it even if it's enabled on per peer level. | |
| bool enable_flex_fec_support = false; | |
| // If true will set conference mode in SDP media section for all video | |
| // tracks for all peers. | |
| bool use_conference_mode = false; | |
| // If specified echo emulation will be done, by mixing the render audio into | |
| // the capture signal. In such case input signal will be reduced by half to | |
| // avoid saturation or compression in the echo path simulation. | |
| absl::optional<EchoEmulationConfig> echo_emulation_config; | |
| }; | |
| // Represent an entity that will report quality metrics after test. | |
| class QualityMetricsReporter : public StatsObserverInterface { | |
| public: | |
| virtual ~QualityMetricsReporter() = default; | |
| // Invoked by framework after peer connection factory and peer connection | |
| // itself will be created but before offer/answer exchange will be started. | |
| // `test_case_name` is name of test case, that should be used to report all | |
| // metrics. | |
| // `reporter_helper` is a pointer to a class that will allow track_id to | |
| // stream_id matching. The caller is responsible for ensuring the | |
| // TrackIdStreamInfoMap will be valid from Start() to | |
| // StopAndReportResults(). | |
| virtual void Start(absl::string_view test_case_name, | |
| const TrackIdStreamInfoMap* reporter_helper) = 0; | |
| // Invoked by framework after call is ended and peer connection factory and | |
| // peer connection are destroyed. | |
| virtual void StopAndReportResults() = 0; | |
| }; | |
| // Represents single participant in call and can be used to perform different | |
| // in-call actions. Might be extended in future. | |
| class PeerHandle { | |
| public: | |
| virtual ~PeerHandle() = default; | |
| }; | |
| virtual ~PeerConnectionE2EQualityTestFixture() = default; | |
| // Add activity that will be executed on the best effort at least after | |
| // `target_time_since_start` after call will be set up (after offer/answer | |
| // exchange, ICE gathering will be done and ICE candidates will passed to | |
| // remote side). `func` param is amount of time spent from the call set up. | |
| virtual void ExecuteAt(TimeDelta target_time_since_start, | |
| std::function<void(TimeDelta)> func) = 0; | |
| // Add activity that will be executed every `interval` with first execution | |
| // on the best effort at least after `initial_delay_since_start` after call | |
| // will be set up (after all participants will be connected). `func` param is | |
| // amount of time spent from the call set up. | |
| virtual void ExecuteEvery(TimeDelta initial_delay_since_start, | |
| TimeDelta interval, | |
| std::function<void(TimeDelta)> func) = 0; | |
| // Add stats reporter entity to observe the test. | |
| virtual void AddQualityMetricsReporter( | |
| std::unique_ptr<QualityMetricsReporter> quality_metrics_reporter) = 0; | |
| // Add a new peer to the call and return an object through which caller | |
| // can configure peer's behavior. | |
| // `network_dependencies` are used to provide networking for peer's peer | |
| // connection. Members must be non-null. | |
| // `configurer` function will be used to configure peer in the call. | |
| virtual PeerHandle* AddPeer( | |
| const PeerNetworkDependencies& network_dependencies, | |
| rtc::FunctionView<void(PeerConfigurer*)> configurer) = 0; | |
| // Runs the media quality test, which includes setting up the call with | |
| // configured participants, running it according to provided `run_params` and | |
| // terminating it properly at the end. During call duration media quality | |
| // metrics are gathered, which are then reported to stdout and (if configured) | |
| // to the json/protobuf output file through the WebRTC perf test results | |
| // reporting system. | |
| virtual void Run(RunParams run_params) = 0; | |
| // Returns real test duration - the time of test execution measured during | |
| // test. Client must call this method only after test is finished (after | |
| // Run(...) method returned). Test execution time is time from end of call | |
| // setup (offer/answer, ICE candidates exchange done and ICE connected) to | |
| // start of call tear down (PeerConnection closed). | |
| virtual TimeDelta GetRealTestDuration() const = 0; | |
| }; | |
| } // namespace webrtc_pc_e2e | |
| } // namespace webrtc | |
| #endif // API_TEST_PEERCONNECTION_QUALITY_TEST_FIXTURE_H_ |