Line data Source code
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/report_block.h"
12 :
13 : #include "webrtc/base/checks.h"
14 : #include "webrtc/base/logging.h"
15 : #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
16 :
17 : namespace webrtc {
18 : namespace rtcp {
19 :
20 : // From RFC 3550, RTP: A Transport Protocol for Real-Time Applications.
21 : //
22 : // RTCP report block (RFC 3550).
23 : //
24 : // 0 1 2 3
25 : // 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
26 : // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
27 : // 0 | SSRC_1 (SSRC of first source) |
28 : // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
29 : // 4 | fraction lost | cumulative number of packets lost |
30 : // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
31 : // 8 | extended highest sequence number received |
32 : // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
33 : // 12 | interarrival jitter |
34 : // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35 : // 16 | last SR (LSR) |
36 : // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
37 : // 20 | delay since last SR (DLSR) |
38 : // 24 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
39 0 : ReportBlock::ReportBlock()
40 : : source_ssrc_(0),
41 : fraction_lost_(0),
42 : cumulative_lost_(0),
43 : extended_high_seq_num_(0),
44 : jitter_(0),
45 : last_sr_(0),
46 0 : delay_since_last_sr_(0) {}
47 :
48 0 : bool ReportBlock::Parse(const uint8_t* buffer, size_t length) {
49 0 : RTC_DCHECK(buffer != nullptr);
50 0 : if (length < ReportBlock::kLength) {
51 0 : LOG(LS_ERROR) << "Report Block should be 24 bytes long";
52 0 : return false;
53 : }
54 :
55 0 : source_ssrc_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[0]);
56 0 : fraction_lost_ = buffer[4];
57 0 : cumulative_lost_ = ByteReader<uint32_t, 3>::ReadBigEndian(&buffer[5]);
58 0 : extended_high_seq_num_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[8]);
59 0 : jitter_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[12]);
60 0 : last_sr_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[16]);
61 0 : delay_since_last_sr_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[20]);
62 :
63 0 : return true;
64 : }
65 :
66 0 : void ReportBlock::Create(uint8_t* buffer) const {
67 : // Runtime check should be done while setting cumulative_lost.
68 0 : RTC_DCHECK_LT(cumulative_lost(), (1 << 24)); // Have only 3 bytes for it.
69 :
70 0 : ByteWriter<uint32_t>::WriteBigEndian(&buffer[0], source_ssrc());
71 0 : ByteWriter<uint8_t>::WriteBigEndian(&buffer[4], fraction_lost());
72 0 : ByteWriter<uint32_t, 3>::WriteBigEndian(&buffer[5], cumulative_lost());
73 0 : ByteWriter<uint32_t>::WriteBigEndian(&buffer[8], extended_high_seq_num());
74 0 : ByteWriter<uint32_t>::WriteBigEndian(&buffer[12], jitter());
75 0 : ByteWriter<uint32_t>::WriteBigEndian(&buffer[16], last_sr());
76 0 : ByteWriter<uint32_t>::WriteBigEndian(&buffer[20], delay_since_last_sr());
77 0 : }
78 :
79 0 : bool ReportBlock::SetCumulativeLost(uint32_t cumulative_lost) {
80 0 : if (cumulative_lost >= (1u << 24)) { // Have only 3 bytes to store it.
81 0 : LOG(LS_WARNING) << "Cumulative lost is too big to fit into Report Block";
82 0 : return false;
83 : }
84 0 : cumulative_lost_ = cumulative_lost;
85 0 : return true;
86 : }
87 :
88 : } // namespace rtcp
89 : } // namespace webrtc
|