1 /*
2  *  Copyright (c) 2014 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 MODULES_PACING_BITRATE_PROBER_H_
12 #define MODULES_PACING_BITRATE_PROBER_H_
13 
14 #include <queue>
15 
16 #include "modules/include/module_common_types.h"
17 #include "rtc_base/basictypes.h"
18 #include "typedefs.h"  // NOLINT(build/include)
19 
20 namespace webrtc {
21 class RtcEventLog;
22 
23 // Note that this class isn't thread-safe by itself and therefore relies
24 // on being protected by the caller.
25 class BitrateProber {
26  public:
27   BitrateProber();
28   explicit BitrateProber(RtcEventLog* event_log);
29 
30   void SetEnabled(bool enable);
31 
32   // Returns true if the prober is in a probing session, i.e., it currently
33   // wants packets to be sent out according to the time returned by
34   // TimeUntilNextProbe().
35   bool IsProbing() const;
36 
37   // Initializes a new probing session if the prober is allowed to probe. Does
38   // not initialize the prober unless the packet size is large enough to probe
39   // with.
40   void OnIncomingPacket(size_t packet_size);
41 
42   // Create a cluster used to probe for |bitrate_bps| with |num_probes| number
43   // of probes.
44   void CreateProbeCluster(int bitrate_bps, int64_t now_ms);
45 
46   // Returns the number of milliseconds until the next probe should be sent to
47   // get accurate probing.
48   int TimeUntilNextProbe(int64_t now_ms);
49 
50   // Information about the current probing cluster.
51   PacedPacketInfo CurrentCluster() const;
52 
53   // Returns the minimum number of bytes that the prober recommends for
54   // the next probe.
55   size_t RecommendedMinProbeSize() const;
56 
57   // Called to report to the prober that a probe has been sent. In case of
58   // multiple packets per probe, this call would be made at the end of sending
59   // the last packet in probe. |probe_size| is the total size of all packets
60   // in probe.
61   void ProbeSent(int64_t now_ms, size_t probe_size);
62 
63  private:
64   enum class ProbingState {
65     // Probing will not be triggered in this state at all times.
66     kDisabled,
67     // Probing is enabled and ready to trigger on the first packet arrival.
68     kInactive,
69     // Probe cluster is filled with the set of data rates to be probed and
70     // probes are being sent.
71     kActive,
72     // Probing is enabled, but currently suspended until an explicit trigger
73     // to start probing again.
74     kSuspended,
75   };
76 
77   // A probe cluster consists of a set of probes. Each probe in turn can be
78   // divided into a number of packets to accommodate the MTU on the network.
79   struct ProbeCluster {
80     PacedPacketInfo pace_info;
81 
82     int sent_probes = 0;
83     int sent_bytes = 0;
84     int64_t time_created_ms = -1;
85     int64_t time_started_ms = -1;
86     int retries = 0;
87   };
88 
89   // Resets the state of the prober and clears any cluster/timing data tracked.
90   void ResetState(int64_t now_ms);
91 
92   int64_t GetNextProbeTime(const ProbeCluster& cluster);
93 
94   ProbingState probing_state_;
95 
96   // Probe bitrate per packet. These are used to compute the delta relative to
97   // the previous probe packet based on the size and time when that packet was
98   // sent.
99   std::queue<ProbeCluster> clusters_;
100 
101   // Time the next probe should be sent when in kActive state.
102   int64_t next_probe_time_ms_;
103 
104   int next_cluster_id_;
105   RtcEventLog* const event_log_;
106 };
107 
108 }  // namespace webrtc
109 
110 #endif  // MODULES_PACING_BITRATE_PROBER_H_
111