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 #include "test/pc/e2e/analyzer/video/default_video_quality_analyzer_stream_state.h"
12
13 #include <map>
14 #include <set>
15
16 #include "absl/types/optional.h"
17 #include "api/units/timestamp.h"
18 #include "rtc_base/checks.h"
19
20 namespace webrtc {
21 namespace {
22
23 template <typename T>
MaybeGetValue(const std::map<size_t,T> & map,size_t key)24 absl::optional<T> MaybeGetValue(const std::map<size_t, T>& map, size_t key) {
25 auto it = map.find(key);
26 if (it == map.end()) {
27 return absl::nullopt;
28 }
29 return it->second;
30 }
31
32 } // namespace
33
StreamState(size_t sender,std::set<size_t> receivers,Timestamp stream_started_time)34 StreamState::StreamState(size_t sender,
35 std::set<size_t> receivers,
36 Timestamp stream_started_time)
37 : sender_(sender),
38 stream_started_time_(stream_started_time),
39 receivers_(receivers),
40 frame_ids_(std::move(receivers)) {
41 frame_ids_.AddReader(kAliveFramesQueueIndex);
42 RTC_CHECK_NE(sender_, kAliveFramesQueueIndex);
43 for (size_t receiver : receivers_) {
44 RTC_CHECK_NE(receiver, kAliveFramesQueueIndex);
45 }
46 }
47
PopFront(size_t peer)48 uint16_t StreamState::PopFront(size_t peer) {
49 RTC_CHECK_NE(peer, kAliveFramesQueueIndex);
50 absl::optional<uint16_t> frame_id = frame_ids_.PopFront(peer);
51 RTC_DCHECK(frame_id.has_value());
52
53 // If alive's frame queue is longer than all others, than also pop frame from
54 // it, because that frame is received by all receivers.
55 size_t alive_size = frame_ids_.size(kAliveFramesQueueIndex);
56 size_t other_size = GetLongestReceiverQueue();
57 // Pops frame from alive queue if alive's queue is the longest one.
58 if (alive_size > other_size) {
59 absl::optional<uint16_t> alive_frame_id =
60 frame_ids_.PopFront(kAliveFramesQueueIndex);
61 RTC_DCHECK(alive_frame_id.has_value());
62 RTC_DCHECK_EQ(frame_id.value(), alive_frame_id.value());
63 }
64
65 return frame_id.value();
66 }
67
AddPeer(size_t peer)68 void StreamState::AddPeer(size_t peer) {
69 RTC_CHECK_NE(peer, kAliveFramesQueueIndex);
70 frame_ids_.AddReader(peer, kAliveFramesQueueIndex);
71 receivers_.insert(peer);
72 }
73
RemovePeer(size_t peer)74 void StreamState::RemovePeer(size_t peer) {
75 RTC_CHECK_NE(peer, kAliveFramesQueueIndex);
76 frame_ids_.RemoveReader(peer);
77 receivers_.erase(peer);
78
79 // If we removed the last receiver for the alive frames, we need to pop them
80 // from the queue, because now they received by all receivers.
81 size_t alive_size = frame_ids_.size(kAliveFramesQueueIndex);
82 size_t other_size = GetLongestReceiverQueue();
83 while (alive_size > other_size) {
84 frame_ids_.PopFront(kAliveFramesQueueIndex);
85 alive_size--;
86 }
87 }
88
MarkNextAliveFrameAsDead()89 uint16_t StreamState::MarkNextAliveFrameAsDead() {
90 absl::optional<uint16_t> frame_id =
91 frame_ids_.PopFront(kAliveFramesQueueIndex);
92 RTC_DCHECK(frame_id.has_value());
93 return frame_id.value();
94 }
95
SetLastRenderedFrameTime(size_t peer,Timestamp time)96 void StreamState::SetLastRenderedFrameTime(size_t peer, Timestamp time) {
97 auto it = last_rendered_frame_time_.find(peer);
98 if (it == last_rendered_frame_time_.end()) {
99 last_rendered_frame_time_.insert({peer, time});
100 } else {
101 it->second = time;
102 }
103 }
104
last_rendered_frame_time(size_t peer) const105 absl::optional<Timestamp> StreamState::last_rendered_frame_time(
106 size_t peer) const {
107 return MaybeGetValue(last_rendered_frame_time_, peer);
108 }
109
GetLongestReceiverQueue() const110 size_t StreamState::GetLongestReceiverQueue() const {
111 size_t max = 0;
112 for (size_t receiver : receivers_) {
113 size_t cur_size = frame_ids_.size(receiver);
114 if (cur_size > max) {
115 max = cur_size;
116 }
117 }
118 return max;
119 }
120
121 } // namespace webrtc
122