1 /* 2 * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef TEST_PC_E2E_ANALYZER_VIDEO_VIDEO_QUALITY_ANALYZER_INJECTION_HELPER_H_ 12 #define TEST_PC_E2E_ANALYZER_VIDEO_VIDEO_QUALITY_ANALYZER_INJECTION_HELPER_H_ 13 14 #include <map> 15 #include <memory> 16 #include <string> 17 #include <vector> 18 19 #include "absl/strings/string_view.h" 20 #include "api/array_view.h" 21 #include "api/test/peerconnection_quality_test_fixture.h" 22 #include "api/test/stats_observer_interface.h" 23 #include "api/test/video_quality_analyzer_interface.h" 24 #include "api/video/video_frame.h" 25 #include "api/video/video_sink_interface.h" 26 #include "api/video_codecs/video_decoder_factory.h" 27 #include "api/video_codecs/video_encoder_factory.h" 28 #include "rtc_base/synchronization/mutex.h" 29 #include "test/pc/e2e/analyzer/video/encoded_image_data_injector.h" 30 #include "test/pc/e2e/analyzer/video/id_generator.h" 31 #include "test/test_video_capturer.h" 32 #include "test/testsupport/video_frame_writer.h" 33 34 namespace webrtc { 35 namespace webrtc_pc_e2e { 36 37 // Provides factory methods for components, that will be used to inject 38 // VideoQualityAnalyzerInterface into PeerConnection pipeline. 39 class VideoQualityAnalyzerInjectionHelper : public StatsObserverInterface { 40 public: 41 using VideoConfig = PeerConnectionE2EQualityTestFixture::VideoConfig; 42 43 VideoQualityAnalyzerInjectionHelper( 44 std::unique_ptr<VideoQualityAnalyzerInterface> analyzer, 45 EncodedImageDataInjector* injector, 46 EncodedImageDataExtractor* extractor); 47 ~VideoQualityAnalyzerInjectionHelper() override; 48 49 // Wraps video encoder factory to give video quality analyzer access to frames 50 // before encoding and encoded images after. 51 std::unique_ptr<VideoEncoderFactory> WrapVideoEncoderFactory( 52 absl::string_view peer_name, 53 std::unique_ptr<VideoEncoderFactory> delegate, 54 double bitrate_multiplier, 55 std::map<std::string, absl::optional<int>> stream_required_spatial_index) 56 const; 57 // Wraps video decoder factory to give video quality analyzer access to 58 // received encoded images and frames, that were decoded from them. 59 std::unique_ptr<VideoDecoderFactory> WrapVideoDecoderFactory( 60 absl::string_view peer_name, 61 std::unique_ptr<VideoDecoderFactory> delegate) const; 62 63 // Creates VideoFrame preprocessor, that will allow video quality analyzer to 64 // get access to the captured frames. If provided config also specifies 65 // |input_dump_file_name|, video will be written into that file. 66 std::unique_ptr<test::TestVideoCapturer::FramePreprocessor> 67 CreateFramePreprocessor(absl::string_view peer_name, 68 const VideoConfig& config); 69 // Creates sink, that will allow video quality analyzer to get access to 70 // the rendered frames. If corresponding video track has 71 // |output_dump_file_name| in its VideoConfig, then video also will be written 72 // into that file. 73 std::unique_ptr<rtc::VideoSinkInterface<VideoFrame>> CreateVideoSink( 74 absl::string_view peer_name); 75 76 void Start(std::string test_case_name, 77 rtc::ArrayView<const std::string> peer_names, 78 int max_threads_count); 79 80 // Forwards |stats_reports| for Peer Connection |pc_label| to 81 // |analyzer_|. 82 void OnStatsReports( 83 absl::string_view pc_label, 84 const rtc::scoped_refptr<const RTCStatsReport>& report) override; 85 86 // Stops VideoQualityAnalyzerInterface to populate final data and metrics. 87 // Should be invoked after analyzed video tracks are disposed. 88 void Stop(); 89 90 private: 91 class AnalyzingVideoSink final : public rtc::VideoSinkInterface<VideoFrame> { 92 public: AnalyzingVideoSink(absl::string_view peer_name,VideoQualityAnalyzerInjectionHelper * helper)93 explicit AnalyzingVideoSink(absl::string_view peer_name, 94 VideoQualityAnalyzerInjectionHelper* helper) 95 : peer_name_(peer_name), helper_(helper) {} 96 ~AnalyzingVideoSink() override = default; 97 OnFrame(const VideoFrame & frame)98 void OnFrame(const VideoFrame& frame) override { 99 helper_->OnFrame(peer_name_, frame); 100 } 101 102 private: 103 const std::string peer_name_; 104 VideoQualityAnalyzerInjectionHelper* const helper_; 105 }; 106 107 test::VideoFrameWriter* MaybeCreateVideoWriter( 108 absl::optional<std::string> file_name, 109 const PeerConnectionE2EQualityTestFixture::VideoConfig& config); 110 // Creates a deep copy of the frame and passes it to the video analyzer, while 111 // passing real frame to the sinks 112 void OnFrame(absl::string_view peer_name, const VideoFrame& frame); 113 std::vector<std::unique_ptr<rtc::VideoSinkInterface<VideoFrame>>>* 114 PopulateSinks(const std::string& stream_label); 115 116 std::unique_ptr<VideoQualityAnalyzerInterface> analyzer_; 117 EncodedImageDataInjector* injector_; 118 EncodedImageDataExtractor* extractor_; 119 120 std::vector<std::unique_ptr<test::VideoFrameWriter>> video_writers_; 121 122 Mutex lock_; 123 std::map<std::string, VideoConfig> known_video_configs_ RTC_GUARDED_BY(lock_); 124 std::map<std::string, 125 std::vector<std::unique_ptr<rtc::VideoSinkInterface<VideoFrame>>>> 126 sinks_ RTC_GUARDED_BY(lock_); 127 128 std::unique_ptr<IdGenerator<int>> encoding_entities_id_generator_; 129 }; 130 131 } // namespace webrtc_pc_e2e 132 } // namespace webrtc 133 134 #endif // TEST_PC_E2E_ANALYZER_VIDEO_VIDEO_QUALITY_ANALYZER_INJECTION_HELPER_H_ 135