1 /*
2 * Copyright (c) 2015 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 "webrtc/modules/rtp_rtcp/source/rtcp_packet/voip_metric.h"
12
13 #include "webrtc/base/checks.h"
14 #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
15
16 namespace webrtc {
17 namespace rtcp {
18 // VoIP Metrics Report Block (RFC 3611).
19 //
20 // 0 1 2 3
21 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
22 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23 // 0 | BT=7 | reserved | block length = 8 |
24 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
25 // 4 | SSRC of source |
26 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
27 // 8 | loss rate | discard rate | burst density | gap density |
28 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
29 // 12 | burst duration | gap duration |
30 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
31 // 16 | round trip delay | end system delay |
32 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
33 // 20 | signal level | noise level | RERL | Gmin |
34 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35 // 24 | R factor | ext. R factor | MOS-LQ | MOS-CQ |
36 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
37 // 28 | RX config | reserved | JB nominal |
38 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
39 // 32 | JB maximum | JB abs max |
40 // 36 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
VoipMetric()41 VoipMetric::VoipMetric() : ssrc_(0) {
42 memset(&voip_metric_, 0, sizeof(voip_metric_));
43 }
44
Parse(const uint8_t * buffer)45 void VoipMetric::Parse(const uint8_t* buffer) {
46 RTC_DCHECK(buffer[0] == kBlockType);
47 // reserved = buffer[1];
48 RTC_DCHECK(ByteReader<uint16_t>::ReadBigEndian(&buffer[2]) == kBlockLength);
49 ssrc_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[4]);
50 voip_metric_.lossRate = buffer[8];
51 voip_metric_.discardRate = buffer[9];
52 voip_metric_.burstDensity = buffer[10];
53 voip_metric_.gapDensity = buffer[11];
54 voip_metric_.burstDuration = ByteReader<uint16_t>::ReadBigEndian(&buffer[12]);
55 voip_metric_.gapDuration = ByteReader<uint16_t>::ReadBigEndian(&buffer[14]);
56 voip_metric_.roundTripDelay =
57 ByteReader<uint16_t>::ReadBigEndian(&buffer[16]);
58 voip_metric_.endSystemDelay =
59 ByteReader<uint16_t>::ReadBigEndian(&buffer[18]);
60 voip_metric_.signalLevel = buffer[20];
61 voip_metric_.noiseLevel = buffer[21];
62 voip_metric_.RERL = buffer[22];
63 voip_metric_.Gmin = buffer[23];
64 voip_metric_.Rfactor = buffer[24];
65 voip_metric_.extRfactor = buffer[25];
66 voip_metric_.MOSLQ = buffer[26];
67 voip_metric_.MOSCQ = buffer[27];
68 voip_metric_.RXconfig = buffer[28];
69 // reserved = buffer[29];
70 voip_metric_.JBnominal = ByteReader<uint16_t>::ReadBigEndian(&buffer[30]);
71 voip_metric_.JBmax = ByteReader<uint16_t>::ReadBigEndian(&buffer[32]);
72 voip_metric_.JBabsMax = ByteReader<uint16_t>::ReadBigEndian(&buffer[34]);
73 }
74
Create(uint8_t * buffer) const75 void VoipMetric::Create(uint8_t* buffer) const {
76 const uint8_t kReserved = 0;
77 buffer[0] = kBlockType;
78 buffer[1] = kReserved;
79 ByteWriter<uint16_t>::WriteBigEndian(&buffer[2], kBlockLength);
80 ByteWriter<uint32_t>::WriteBigEndian(&buffer[4], ssrc_);
81 buffer[8] = voip_metric_.lossRate;
82 buffer[9] = voip_metric_.discardRate;
83 buffer[10] = voip_metric_.burstDensity;
84 buffer[11] = voip_metric_.gapDensity;
85 ByteWriter<uint16_t>::WriteBigEndian(&buffer[12], voip_metric_.burstDuration);
86 ByteWriter<uint16_t>::WriteBigEndian(&buffer[14], voip_metric_.gapDuration);
87 ByteWriter<uint16_t>::WriteBigEndian(&buffer[16],
88 voip_metric_.roundTripDelay);
89 ByteWriter<uint16_t>::WriteBigEndian(&buffer[18],
90 voip_metric_.endSystemDelay);
91 buffer[20] = voip_metric_.signalLevel;
92 buffer[21] = voip_metric_.noiseLevel;
93 buffer[22] = voip_metric_.RERL;
94 buffer[23] = voip_metric_.Gmin;
95 buffer[24] = voip_metric_.Rfactor;
96 buffer[25] = voip_metric_.extRfactor;
97 buffer[26] = voip_metric_.MOSLQ;
98 buffer[27] = voip_metric_.MOSCQ;
99 buffer[28] = voip_metric_.RXconfig;
100 buffer[29] = kReserved;
101 ByteWriter<uint16_t>::WriteBigEndian(&buffer[30], voip_metric_.JBnominal);
102 ByteWriter<uint16_t>::WriteBigEndian(&buffer[32], voip_metric_.JBmax);
103 ByteWriter<uint16_t>::WriteBigEndian(&buffer[34], voip_metric_.JBabsMax);
104 }
105
106 } // namespace rtcp
107 } // namespace webrtc
108