xref: /aosp_15_r20/external/webrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_stream_state.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_DEFAULT_VIDEO_QUALITY_ANALYZER_STREAM_STATE_H_
12 #define TEST_PC_E2E_ANALYZER_VIDEO_DEFAULT_VIDEO_QUALITY_ANALYZER_STREAM_STATE_H_
13 
14 #include <limits>
15 #include <map>
16 #include <set>
17 
18 #include "absl/types/optional.h"
19 #include "api/units/timestamp.h"
20 #include "test/pc/e2e/analyzer/video/multi_reader_queue.h"
21 
22 namespace webrtc {
23 
24 // Represents a current state of video stream inside
25 // DefaultVideoQualityAnalyzer.
26 //
27 // Maintains the sequence of frames for each video stream and keeps track about
28 // which frames were seen by each of the possible stream receiver.
29 //
30 // Keeps information about which frames are alive and which are dead. Frame is
31 // alive if it contains VideoFrame payload for corresponding FrameInFlight
32 // object inside DefaultVideoQualityAnalyzer, otherwise frame is considered
33 // dead.
34 //
35 // Supports peer indexes from 0 to max(size_t) - 1.
36 class StreamState {
37  public:
38   StreamState(size_t sender,
39               std::set<size_t> receivers,
40               Timestamp stream_started_time);
41 
sender()42   size_t sender() const { return sender_; }
stream_started_time()43   Timestamp stream_started_time() const { return stream_started_time_; }
44 
PushBack(uint16_t frame_id)45   void PushBack(uint16_t frame_id) { frame_ids_.PushBack(frame_id); }
46   // Crash if state is empty.
47   uint16_t PopFront(size_t peer);
IsEmpty(size_t peer)48   bool IsEmpty(size_t peer) const { return frame_ids_.IsEmpty(peer); }
49   // Crash if state is empty.
Front(size_t peer)50   uint16_t Front(size_t peer) const { return frame_ids_.Front(peer).value(); }
51 
52   // Adds a new peer to the state. All currently alive frames will be expected
53   // to be received by the newly added peer.
54   void AddPeer(size_t peer);
55 
56   // Removes peer from the state. Frames that were expected to be received by
57   // this peer will be removed from it. On the other hand last rendered frame
58   // time for the removed peer will be preserved, because
59   // DefaultVideoQualityAnalyzer still may request it for stats processing.
60   void RemovePeer(size_t peer);
61 
GetAliveFramesCount()62   size_t GetAliveFramesCount() const {
63     return frame_ids_.size(kAliveFramesQueueIndex);
64   }
65   uint16_t MarkNextAliveFrameAsDead();
66 
67   void SetLastRenderedFrameTime(size_t peer, Timestamp time);
68   absl::optional<Timestamp> last_rendered_frame_time(size_t peer) const;
69 
70  private:
71   // Index of the `frame_ids_` queue which is used to track alive frames for
72   // this stream.
73   static constexpr size_t kAliveFramesQueueIndex =
74       std::numeric_limits<size_t>::max();
75 
76   size_t GetLongestReceiverQueue() const;
77 
78   // Index of the owner. Owner's queue in `frame_ids_` will keep alive frames.
79   const size_t sender_;
80   const Timestamp stream_started_time_;
81   std::set<size_t> receivers_;
82   // To correctly determine dropped frames we have to know sequence of frames
83   // in each stream so we will keep a list of frame ids inside the stream.
84   // This list is represented by multi head queue of frame ids with separate
85   // head for each receiver. When the frame is rendered, we will pop ids from
86   // the corresponding head until id will match with rendered one. All ids
87   // before matched one can be considered as dropped:
88   //
89   // | frame_id1 |->| frame_id2 |->| frame_id3 |->| frame_id4 |
90   //
91   // If we received frame with id frame_id3, then we will pop frame_id1 and
92   // frame_id2 and consider those frames as dropped and then compare received
93   // frame with the one from `FrameInFlight` with id frame_id3.
94   MultiReaderQueue<uint16_t> frame_ids_;
95   std::map<size_t, Timestamp> last_rendered_frame_time_;
96 };
97 
98 }  // namespace webrtc
99 
100 #endif  // TEST_PC_E2E_ANALYZER_VIDEO_DEFAULT_VIDEO_QUALITY_ANALYZER_STREAM_STATE_H_
101