xref: /aosp_15_r20/external/webrtc/test/pc/e2e/analyzer/video/analyzing_video_sink.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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