[rtp_rtcp] rtcp::Sdes moved into own file
Cleaning/Parsing will be done in the https://codereview.webrtc.org/1439553003/ BUG=webrtc:5260 R=asapersson@webrtc.org, åsapersson Review URL: https://codereview.webrtc.org/1592763002 . Cr-Commit-Position: refs/heads/master@{#11274}
This commit is contained in:
114
webrtc/modules/rtp_rtcp/source/rtcp_packet/sdes.cc
Normal file
114
webrtc/modules/rtp_rtcp/source/rtcp_packet/sdes.cc
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/sdes.h"
|
||||
|
||||
#include "webrtc/base/logging.h"
|
||||
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
|
||||
|
||||
using webrtc::RTCPUtility::PT_SDES;
|
||||
|
||||
namespace webrtc {
|
||||
namespace rtcp {
|
||||
namespace {
|
||||
void AssignUWord8(uint8_t* buffer, size_t* offset, uint8_t value) {
|
||||
buffer[(*offset)++] = value;
|
||||
}
|
||||
|
||||
void AssignUWord32(uint8_t* buffer, size_t* offset, uint32_t value) {
|
||||
ByteWriter<uint32_t>::WriteBigEndian(buffer + *offset, value);
|
||||
*offset += 4;
|
||||
}
|
||||
// Source Description (SDES) (RFC 3550).
|
||||
//
|
||||
// 0 1 2 3
|
||||
// 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
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// header |V=2|P| SC | PT=SDES=202 | length |
|
||||
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||
// chunk | SSRC/CSRC_1 |
|
||||
// 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | SDES items |
|
||||
// | ... |
|
||||
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||
// chunk | SSRC/CSRC_2 |
|
||||
// 2 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | SDES items |
|
||||
// | ... |
|
||||
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||
//
|
||||
// Canonical End-Point Identifier SDES Item (CNAME)
|
||||
//
|
||||
// 0 1 2 3
|
||||
// 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
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | CNAME=1 | length | user and domain name ...
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
void CreateSdes(const std::vector<Sdes::Chunk>& chunks,
|
||||
uint8_t* buffer,
|
||||
size_t* pos) {
|
||||
const uint8_t kSdesItemType = 1;
|
||||
for (std::vector<Sdes::Chunk>::const_iterator it = chunks.begin();
|
||||
it != chunks.end(); ++it) {
|
||||
AssignUWord32(buffer, pos, (*it).ssrc);
|
||||
AssignUWord8(buffer, pos, kSdesItemType);
|
||||
AssignUWord8(buffer, pos, (*it).name.length());
|
||||
memcpy(buffer + *pos, (*it).name.data(), (*it).name.length());
|
||||
*pos += (*it).name.length();
|
||||
memset(buffer + *pos, 0, (*it).null_octets);
|
||||
*pos += (*it).null_octets;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool Sdes::Create(uint8_t* packet,
|
||||
size_t* index,
|
||||
size_t max_length,
|
||||
RtcpPacket::PacketReadyCallback* callback) const {
|
||||
assert(!chunks_.empty());
|
||||
while (*index + BlockLength() > max_length) {
|
||||
if (!OnBufferFull(packet, index, callback))
|
||||
return false;
|
||||
}
|
||||
CreateHeader(chunks_.size(), PT_SDES, HeaderLength(), packet, index);
|
||||
CreateSdes(chunks_, packet, index);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Sdes::WithCName(uint32_t ssrc, const std::string& cname) {
|
||||
assert(cname.length() <= 0xff);
|
||||
if (chunks_.size() >= kMaxNumberOfChunks) {
|
||||
LOG(LS_WARNING) << "Max SDES chunks reached.";
|
||||
return false;
|
||||
}
|
||||
// In each chunk, the list of items must be terminated by one or more null
|
||||
// octets. The next chunk must start on a 32-bit boundary.
|
||||
// CNAME (1 byte) | length (1 byte) | name | padding.
|
||||
int null_octets = 4 - ((2 + cname.length()) % 4);
|
||||
Chunk chunk;
|
||||
chunk.ssrc = ssrc;
|
||||
chunk.name = cname;
|
||||
chunk.null_octets = null_octets;
|
||||
chunks_.push_back(chunk);
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t Sdes::BlockLength() const {
|
||||
// Header (4 bytes).
|
||||
// Chunk:
|
||||
// SSRC/CSRC (4 bytes) | CNAME (1 byte) | length (1 byte) | name | padding.
|
||||
size_t length = kHeaderLength;
|
||||
for (const Chunk& chunk : chunks_)
|
||||
length += 6 + chunk.name.length() + chunk.null_octets;
|
||||
assert(length % 4 == 0);
|
||||
return length;
|
||||
}
|
||||
} // namespace rtcp
|
||||
} // namespace webrtc
|
||||
Reference in New Issue
Block a user