-
-
Notifications
You must be signed in to change notification settings - Fork 391
/
Copy pathrtppacketizer.cpp
129 lines (95 loc) · 3.67 KB
/
rtppacketizer.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/**
* Copyright (c) 2020 Filip Klembara (in2core)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#if RTC_ENABLE_MEDIA
#include "rtppacketizer.hpp"
#include <cmath>
#include <cstring>
namespace rtc {
RtpPacketizer::RtpPacketizer(shared_ptr<RtpPacketizationConfig> rtpConfig) : rtpConfig(rtpConfig) {}
RtpPacketizer::~RtpPacketizer() {}
message_ptr RtpPacketizer::packetize(shared_ptr<binary> payload, bool mark) {
size_t rtpExtHeaderSize = 0;
const bool setVideoRotation = (rtpConfig->videoOrientationId != 0) &&
(rtpConfig->videoOrientationId <
15) && // needs fixing if longer extension headers are supported
mark &&
(rtpConfig->videoOrientation != 0);
if (setVideoRotation)
rtpExtHeaderSize += 2;
const bool setPlayoutDelay = (rtpConfig->playoutDelayId > 0 && rtpConfig->playoutDelayId < 15);
if (setPlayoutDelay)
rtpExtHeaderSize += 1;
if (rtpConfig->mid.has_value())
rtpExtHeaderSize += (1 + rtpConfig->mid->length());
if (rtpConfig->rid.has_value())
rtpExtHeaderSize += (1 + rtpConfig->rid->length());
if (rtpExtHeaderSize != 0)
rtpExtHeaderSize += 4;
rtpExtHeaderSize = (rtpExtHeaderSize + 3) & ~3;
auto message = make_message(RtpHeaderSize + rtpExtHeaderSize + payload->size());
auto *rtp = (RtpHeader *)message->data();
rtp->setPayloadType(rtpConfig->payloadType);
rtp->setSeqNumber(rtpConfig->sequenceNumber++); // increase sequence number
rtp->setTimestamp(rtpConfig->timestamp);
rtp->setSsrc(rtpConfig->ssrc);
if (mark) {
rtp->setMarker(true);
}
if (rtpExtHeaderSize) {
rtp->setExtension(true);
auto extHeader = rtp->getExtensionHeader();
extHeader->setProfileSpecificId(0xbede);
auto headerLength = static_cast<uint16_t>(rtpExtHeaderSize / 4) - 1;
extHeader->setHeaderLength(headerLength);
extHeader->clearBody();
size_t offset = 0;
if (setVideoRotation) {
extHeader->writeCurrentVideoOrientation(offset, rtpConfig->videoOrientationId,
rtpConfig->videoOrientation);
offset += 2;
}
if (rtpConfig->mid.has_value()) {
extHeader->writeOneByteHeader(
offset, rtpConfig->midId,
reinterpret_cast<const std::byte *>(rtpConfig->mid->c_str()),
rtpConfig->mid->length());
offset += (1 + rtpConfig->mid->length());
}
if (rtpConfig->rid.has_value()) {
extHeader->writeOneByteHeader(
offset, rtpConfig->ridId,
reinterpret_cast<const std::byte *>(rtpConfig->rid->c_str()),
rtpConfig->rid->length());
}
if (setPlayoutDelay) {
uint16_t min = rtpConfig->playoutDelayMin & 0xFFF;
uint16_t max = rtpConfig->playoutDelayMax & 0xFFF;
// 12 bits for min + 12 bits for max
char data[] = {
static_cast<char>((min >> 4) & 0xFF),
static_cast<char>(((min & 0xF) << 4) | ((max >> 8) & 0xF)),
static_cast<char>(max & 0xFF)
};
extHeader->writeOneByteHeader(offset, rtpConfig->playoutDelayId, (byte *)data, 3);
offset += 4;
}
}
rtp->preparePacket();
std::memcpy(message->data() + RtpHeaderSize + rtpExtHeaderSize, payload->data(),
payload->size());
return message;
}
void RtpPacketizer::media([[maybe_unused]] const Description::Media &desc) {}
void RtpPacketizer::outgoing([[maybe_unused]] message_vector &messages,
[[maybe_unused]] const message_callback &send) {
// Default implementation
for (auto &message : messages)
message = packetize(message, false);
}
} // namespace rtc
#endif /* RTC_ENABLE_MEDIA */