1 /* 2 * Copyright (c) 2022 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_ANALYZING_VIDEO_SINK_H_ 12 #define TEST_PC_E2E_ANALYZER_VIDEO_ANALYZING_VIDEO_SINK_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/numerics/samples_stats_counter.h" 21 #include "api/test/pclf/media_configuration.h" 22 #include "api/test/video/video_frame_writer.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 "rtc_base/synchronization/mutex.h" 27 #include "rtc_base/thread_annotations.h" 28 #include "system_wrappers/include/clock.h" 29 #include "test/pc/e2e/analyzer/video/analyzing_video_sinks_helper.h" 30 31 namespace webrtc { 32 namespace webrtc_pc_e2e { 33 34 // A sink to inject video quality analyzer as a sink into WebRTC. 35 class AnalyzingVideoSink : public rtc::VideoSinkInterface<VideoFrame> { 36 public: 37 struct Stats { 38 // Time required to scale video frame to the requested rendered resolution. 39 // Collected only for frames with ID set and iff `report_infra_stats` is 40 // true. 41 SamplesStatsCounter scaling_tims_ms; 42 // Time required to process single video frame. Collected only for frames 43 // with ID set and iff `report_infra_stats` is true. 44 SamplesStatsCounter analyzing_sink_processing_time_ms; 45 }; 46 47 AnalyzingVideoSink(absl::string_view peer_name, 48 Clock* clock, 49 VideoQualityAnalyzerInterface& analyzer, 50 AnalyzingVideoSinksHelper& sinks_helper, 51 const VideoSubscription& subscription, 52 bool report_infra_stats); 53 54 // Updates subscription used by this peer to render received video. 55 void UpdateSubscription(const VideoSubscription& subscription); 56 57 void OnFrame(const VideoFrame& frame) override; 58 59 Stats stats() const; 60 61 private: 62 struct SinksDescriptor { SinksDescriptorSinksDescriptor63 SinksDescriptor(absl::string_view sender_peer_name, 64 const VideoResolution& resolution) 65 : sender_peer_name(sender_peer_name), resolution(resolution) {} 66 67 // Required to be able to resolve resolutions on new subscription and 68 // understand if we need to recreate `video_frame_writer` and `sinks`. 69 std::string sender_peer_name; 70 // Resolution which was used to create `video_frame_writer` and `sinks`. 71 VideoResolution resolution; 72 73 // Is set if dumping of output video was requested; 74 test::VideoFrameWriter* video_frame_writer = nullptr; 75 std::vector<std::unique_ptr<rtc::VideoSinkInterface<VideoFrame>>> sinks; 76 }; 77 78 // Scales video frame to `required_resolution` if necessary. Crashes if video 79 // frame and `required_resolution` have different aspect ratio. 80 VideoFrame ScaleVideoFrame(const VideoFrame& frame, 81 const VideoResolution& required_resolution) 82 RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 83 // Creates full copy of the frame to free any frame owned internal buffers 84 // and passes created copy to analyzer. Uses `I420Buffer` to represent 85 // frame content. 86 void AnalyzeFrame(const VideoFrame& frame); 87 // Populates sink for specified stream and caches them in `stream_sinks_`. 88 SinksDescriptor* PopulateSinks(absl::string_view stream_label) 89 RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 90 91 const std::string peer_name_; 92 const bool report_infra_stats_; 93 Clock* const clock_; 94 VideoQualityAnalyzerInterface* const analyzer_; 95 AnalyzingVideoSinksHelper* const sinks_helper_; 96 97 mutable Mutex mutex_; 98 VideoSubscription subscription_ RTC_GUARDED_BY(mutex_); 99 std::map<std::string, SinksDescriptor> stream_sinks_ RTC_GUARDED_BY(mutex_); 100 Stats stats_ RTC_GUARDED_BY(mutex_); 101 }; 102 103 } // namespace webrtc_pc_e2e 104 } // namespace webrtc 105 106 #endif // TEST_PC_E2E_ANALYZER_VIDEO_ANALYZING_VIDEO_SINK_H_ 107