xref: /aosp_15_r20/external/webrtc/test/scenario/video_frame_matcher.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2018 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker #ifndef TEST_SCENARIO_VIDEO_FRAME_MATCHER_H_
11*d9f75844SAndroid Build Coastguard Worker #define TEST_SCENARIO_VIDEO_FRAME_MATCHER_H_
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include <deque>
14*d9f75844SAndroid Build Coastguard Worker #include <map>
15*d9f75844SAndroid Build Coastguard Worker #include <memory>
16*d9f75844SAndroid Build Coastguard Worker #include <set>
17*d9f75844SAndroid Build Coastguard Worker #include <string>
18*d9f75844SAndroid Build Coastguard Worker #include <vector>
19*d9f75844SAndroid Build Coastguard Worker 
20*d9f75844SAndroid Build Coastguard Worker #include "api/units/timestamp.h"
21*d9f75844SAndroid Build Coastguard Worker #include "api/video/video_frame.h"
22*d9f75844SAndroid Build Coastguard Worker #include "api/video/video_sink_interface.h"
23*d9f75844SAndroid Build Coastguard Worker #include "api/video/video_source_interface.h"
24*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ref_counted_object.h"
25*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/task_queue_for_test.h"
26*d9f75844SAndroid Build Coastguard Worker #include "system_wrappers/include/clock.h"
27*d9f75844SAndroid Build Coastguard Worker #include "test/scenario/performance_stats.h"
28*d9f75844SAndroid Build Coastguard Worker 
29*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
30*d9f75844SAndroid Build Coastguard Worker namespace test {
31*d9f75844SAndroid Build Coastguard Worker 
32*d9f75844SAndroid Build Coastguard Worker class VideoFrameMatcher {
33*d9f75844SAndroid Build Coastguard Worker  public:
34*d9f75844SAndroid Build Coastguard Worker   explicit VideoFrameMatcher(
35*d9f75844SAndroid Build Coastguard Worker       std::vector<std::function<void(const VideoFramePair&)>>
36*d9f75844SAndroid Build Coastguard Worker           frame_pair_handlers);
37*d9f75844SAndroid Build Coastguard Worker   ~VideoFrameMatcher();
38*d9f75844SAndroid Build Coastguard Worker   void RegisterLayer(int layer_id);
39*d9f75844SAndroid Build Coastguard Worker   void OnCapturedFrame(const VideoFrame& frame, Timestamp at_time);
40*d9f75844SAndroid Build Coastguard Worker   void OnDecodedFrame(const VideoFrame& frame,
41*d9f75844SAndroid Build Coastguard Worker                       int layer_id,
42*d9f75844SAndroid Build Coastguard Worker                       Timestamp render_time,
43*d9f75844SAndroid Build Coastguard Worker                       Timestamp at_time);
44*d9f75844SAndroid Build Coastguard Worker   bool Active() const;
45*d9f75844SAndroid Build Coastguard Worker 
46*d9f75844SAndroid Build Coastguard Worker  private:
47*d9f75844SAndroid Build Coastguard Worker   struct DecodedFrameBase {
48*d9f75844SAndroid Build Coastguard Worker     int id;
49*d9f75844SAndroid Build Coastguard Worker     Timestamp decoded_time = Timestamp::PlusInfinity();
50*d9f75844SAndroid Build Coastguard Worker     Timestamp render_time = Timestamp::PlusInfinity();
51*d9f75844SAndroid Build Coastguard Worker     rtc::scoped_refptr<VideoFrameBuffer> frame;
52*d9f75844SAndroid Build Coastguard Worker     rtc::scoped_refptr<VideoFrameBuffer> thumb;
53*d9f75844SAndroid Build Coastguard Worker     int repeat_count = 0;
54*d9f75844SAndroid Build Coastguard Worker   };
55*d9f75844SAndroid Build Coastguard Worker   using DecodedFrame = rtc::FinalRefCountedObject<DecodedFrameBase>;
56*d9f75844SAndroid Build Coastguard Worker   struct CapturedFrame {
57*d9f75844SAndroid Build Coastguard Worker     int id;
58*d9f75844SAndroid Build Coastguard Worker     Timestamp capture_time = Timestamp::PlusInfinity();
59*d9f75844SAndroid Build Coastguard Worker     rtc::scoped_refptr<VideoFrameBuffer> frame;
60*d9f75844SAndroid Build Coastguard Worker     rtc::scoped_refptr<VideoFrameBuffer> thumb;
61*d9f75844SAndroid Build Coastguard Worker     double best_score = INFINITY;
62*d9f75844SAndroid Build Coastguard Worker     rtc::scoped_refptr<DecodedFrame> best_decode;
63*d9f75844SAndroid Build Coastguard Worker     bool matched = false;
64*d9f75844SAndroid Build Coastguard Worker   };
65*d9f75844SAndroid Build Coastguard Worker   struct VideoLayer {
66*d9f75844SAndroid Build Coastguard Worker     int layer_id;
67*d9f75844SAndroid Build Coastguard Worker     std::deque<CapturedFrame> captured_frames;
68*d9f75844SAndroid Build Coastguard Worker     rtc::scoped_refptr<DecodedFrame> last_decode;
69*d9f75844SAndroid Build Coastguard Worker     int next_decoded_id = 1;
70*d9f75844SAndroid Build Coastguard Worker   };
71*d9f75844SAndroid Build Coastguard Worker   void HandleMatch(CapturedFrame captured, int layer_id);
72*d9f75844SAndroid Build Coastguard Worker   void Finalize();
73*d9f75844SAndroid Build Coastguard Worker   int next_capture_id_ = 1;
74*d9f75844SAndroid Build Coastguard Worker   std::vector<std::function<void(const VideoFramePair&)>> frame_pair_handlers_;
75*d9f75844SAndroid Build Coastguard Worker   std::map<int, VideoLayer> layers_;
76*d9f75844SAndroid Build Coastguard Worker   TaskQueueForTest task_queue_;
77*d9f75844SAndroid Build Coastguard Worker };
78*d9f75844SAndroid Build Coastguard Worker 
79*d9f75844SAndroid Build Coastguard Worker class CapturedFrameTap : public rtc::VideoSinkInterface<VideoFrame> {
80*d9f75844SAndroid Build Coastguard Worker  public:
81*d9f75844SAndroid Build Coastguard Worker   CapturedFrameTap(Clock* clock, VideoFrameMatcher* matcher);
82*d9f75844SAndroid Build Coastguard Worker   CapturedFrameTap(CapturedFrameTap&) = delete;
83*d9f75844SAndroid Build Coastguard Worker   CapturedFrameTap& operator=(CapturedFrameTap&) = delete;
84*d9f75844SAndroid Build Coastguard Worker 
85*d9f75844SAndroid Build Coastguard Worker   void OnFrame(const VideoFrame& frame) override;
86*d9f75844SAndroid Build Coastguard Worker   void OnDiscardedFrame() override;
87*d9f75844SAndroid Build Coastguard Worker 
88*d9f75844SAndroid Build Coastguard Worker  private:
89*d9f75844SAndroid Build Coastguard Worker   Clock* const clock_;
90*d9f75844SAndroid Build Coastguard Worker   VideoFrameMatcher* const matcher_;
91*d9f75844SAndroid Build Coastguard Worker   int discarded_count_ = 0;
92*d9f75844SAndroid Build Coastguard Worker };
93*d9f75844SAndroid Build Coastguard Worker 
94*d9f75844SAndroid Build Coastguard Worker class ForwardingCapturedFrameTap
95*d9f75844SAndroid Build Coastguard Worker     : public rtc::VideoSinkInterface<VideoFrame>,
96*d9f75844SAndroid Build Coastguard Worker       public rtc::VideoSourceInterface<VideoFrame> {
97*d9f75844SAndroid Build Coastguard Worker  public:
98*d9f75844SAndroid Build Coastguard Worker   ForwardingCapturedFrameTap(Clock* clock,
99*d9f75844SAndroid Build Coastguard Worker                              VideoFrameMatcher* matcher,
100*d9f75844SAndroid Build Coastguard Worker                              rtc::VideoSourceInterface<VideoFrame>* source);
101*d9f75844SAndroid Build Coastguard Worker   ForwardingCapturedFrameTap(ForwardingCapturedFrameTap&) = delete;
102*d9f75844SAndroid Build Coastguard Worker   ForwardingCapturedFrameTap& operator=(ForwardingCapturedFrameTap&) = delete;
103*d9f75844SAndroid Build Coastguard Worker 
104*d9f75844SAndroid Build Coastguard Worker   // VideoSinkInterface interface
105*d9f75844SAndroid Build Coastguard Worker   void OnFrame(const VideoFrame& frame) override;
106*d9f75844SAndroid Build Coastguard Worker   void OnDiscardedFrame() override;
107*d9f75844SAndroid Build Coastguard Worker 
108*d9f75844SAndroid Build Coastguard Worker   // VideoSourceInterface interface
109*d9f75844SAndroid Build Coastguard Worker   void AddOrUpdateSink(VideoSinkInterface<VideoFrame>* sink,
110*d9f75844SAndroid Build Coastguard Worker                        const rtc::VideoSinkWants& wants) override;
111*d9f75844SAndroid Build Coastguard Worker   void RemoveSink(VideoSinkInterface<VideoFrame>* sink) override;
112*d9f75844SAndroid Build Coastguard Worker 
113*d9f75844SAndroid Build Coastguard Worker  private:
114*d9f75844SAndroid Build Coastguard Worker   Clock* const clock_;
115*d9f75844SAndroid Build Coastguard Worker   VideoFrameMatcher* const matcher_;
116*d9f75844SAndroid Build Coastguard Worker   rtc::VideoSourceInterface<VideoFrame>* const source_;
117*d9f75844SAndroid Build Coastguard Worker   VideoSinkInterface<VideoFrame>* sink_ = nullptr;
118*d9f75844SAndroid Build Coastguard Worker   int discarded_count_ = 0;
119*d9f75844SAndroid Build Coastguard Worker };
120*d9f75844SAndroid Build Coastguard Worker 
121*d9f75844SAndroid Build Coastguard Worker class DecodedFrameTap : public rtc::VideoSinkInterface<VideoFrame> {
122*d9f75844SAndroid Build Coastguard Worker  public:
123*d9f75844SAndroid Build Coastguard Worker   DecodedFrameTap(Clock* clock, VideoFrameMatcher* matcher, int layer_id);
124*d9f75844SAndroid Build Coastguard Worker   // VideoSinkInterface interface
125*d9f75844SAndroid Build Coastguard Worker   void OnFrame(const VideoFrame& frame) override;
126*d9f75844SAndroid Build Coastguard Worker 
127*d9f75844SAndroid Build Coastguard Worker  private:
128*d9f75844SAndroid Build Coastguard Worker   Clock* const clock_;
129*d9f75844SAndroid Build Coastguard Worker   VideoFrameMatcher* const matcher_;
130*d9f75844SAndroid Build Coastguard Worker   int layer_id_;
131*d9f75844SAndroid Build Coastguard Worker };
132*d9f75844SAndroid Build Coastguard Worker }  // namespace test
133*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
134*d9f75844SAndroid Build Coastguard Worker #endif  // TEST_SCENARIO_VIDEO_FRAME_MATCHER_H_
135