• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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