OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 paced_sender_(paced_sender), | 85 paced_sender_(paced_sender), |
86 transport_sequence_number_allocator_(sequence_number_allocator), | 86 transport_sequence_number_allocator_(sequence_number_allocator), |
87 transport_feedback_observer_(transport_feedback_observer), | 87 transport_feedback_observer_(transport_feedback_observer), |
88 last_capture_time_ms_sent_(0), | 88 last_capture_time_ms_sent_(0), |
89 transport_(transport), | 89 transport_(transport), |
90 sending_media_(true), // Default to sending media. | 90 sending_media_(true), // Default to sending media. |
91 max_payload_length_(IP_PACKET_SIZE - 28), // Default is IP-v4/UDP. | 91 max_payload_length_(IP_PACKET_SIZE - 28), // Default is IP-v4/UDP. |
92 payload_type_(-1), | 92 payload_type_(-1), |
93 payload_type_map_(), | 93 payload_type_map_(), |
94 rtp_header_extension_map_(), | 94 rtp_header_extension_map_(), |
95 transmission_time_offset_(0), | |
96 absolute_send_time_(0), | |
97 rotation_(kVideoRotation_0), | |
98 video_rotation_active_(false), | 95 video_rotation_active_(false), |
99 transport_sequence_number_(0), | |
100 playout_delay_active_(false), | 96 playout_delay_active_(false), |
101 packet_history_(clock), | 97 packet_history_(clock), |
102 // Statistics | 98 // Statistics |
103 rtp_stats_callback_(nullptr), | 99 rtp_stats_callback_(nullptr), |
104 total_bitrate_sent_(kBitrateStatisticsWindowMs, | 100 total_bitrate_sent_(kBitrateStatisticsWindowMs, |
105 RateStatistics::kBpsScale), | 101 RateStatistics::kBpsScale), |
106 nack_bitrate_sent_(kBitrateStatisticsWindowMs, RateStatistics::kBpsScale), | 102 nack_bitrate_sent_(kBitrateStatisticsWindowMs, RateStatistics::kBpsScale), |
107 frame_count_observer_(frame_count_observer), | 103 frame_count_observer_(frame_count_observer), |
108 send_side_delay_observer_(send_side_delay_observer), | 104 send_side_delay_observer_(send_side_delay_observer), |
109 event_log_(event_log), | 105 event_log_(event_log), |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 return video_->FecOverheadRate(); | 173 return video_->FecOverheadRate(); |
178 } | 174 } |
179 return 0; | 175 return 0; |
180 } | 176 } |
181 | 177 |
182 uint32_t RTPSender::NackOverheadRate() const { | 178 uint32_t RTPSender::NackOverheadRate() const { |
183 rtc::CritScope cs(&statistics_crit_); | 179 rtc::CritScope cs(&statistics_crit_); |
184 return nack_bitrate_sent_.Rate(clock_->TimeInMilliseconds()).value_or(0); | 180 return nack_bitrate_sent_.Rate(clock_->TimeInMilliseconds()).value_or(0); |
185 } | 181 } |
186 | 182 |
187 int32_t RTPSender::SetTransmissionTimeOffset(int32_t transmission_time_offset) { | |
188 if (transmission_time_offset > (0x800000 - 1) || | |
189 transmission_time_offset < -(0x800000 - 1)) { // Word24. | |
190 return -1; | |
191 } | |
192 rtc::CritScope lock(&send_critsect_); | |
193 transmission_time_offset_ = transmission_time_offset; | |
194 return 0; | |
195 } | |
196 | |
197 int32_t RTPSender::SetAbsoluteSendTime(uint32_t absolute_send_time) { | |
198 if (absolute_send_time > 0xffffff) { // UWord24. | |
199 return -1; | |
200 } | |
201 rtc::CritScope lock(&send_critsect_); | |
202 absolute_send_time_ = absolute_send_time; | |
203 return 0; | |
204 } | |
205 | |
206 void RTPSender::SetVideoRotation(VideoRotation rotation) { | |
207 rtc::CritScope lock(&send_critsect_); | |
208 rotation_ = rotation; | |
209 } | |
210 | |
211 int32_t RTPSender::SetTransportSequenceNumber(uint16_t sequence_number) { | |
212 rtc::CritScope lock(&send_critsect_); | |
213 transport_sequence_number_ = sequence_number; | |
214 return 0; | |
215 } | |
216 | |
217 int32_t RTPSender::RegisterRtpHeaderExtension(RTPExtensionType type, | 183 int32_t RTPSender::RegisterRtpHeaderExtension(RTPExtensionType type, |
218 uint8_t id) { | 184 uint8_t id) { |
219 rtc::CritScope lock(&send_critsect_); | 185 rtc::CritScope lock(&send_critsect_); |
220 switch (type) { | 186 switch (type) { |
221 case kRtpExtensionVideoRotation: | 187 case kRtpExtensionVideoRotation: |
222 video_rotation_active_ = false; | 188 video_rotation_active_ = false; |
223 return rtp_header_extension_map_.RegisterInactive(type, id); | 189 return rtp_header_extension_map_.RegisterInactive(type, id); |
224 case kRtpExtensionPlayoutDelay: | 190 case kRtpExtensionPlayoutDelay: |
225 playout_delay_active_ = false; | 191 playout_delay_active_ = false; |
226 return rtp_header_extension_map_.RegisterInactive(type, id); | 192 return rtp_header_extension_map_.RegisterInactive(type, id); |
(...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
861 | 827 |
862 size_t RTPSender::TimeToSendPadding(size_t bytes, int probe_cluster_id) { | 828 size_t RTPSender::TimeToSendPadding(size_t bytes, int probe_cluster_id) { |
863 if (audio_configured_ || bytes == 0) | 829 if (audio_configured_ || bytes == 0) |
864 return 0; | 830 return 0; |
865 size_t bytes_sent = TrySendRedundantPayloads(bytes, probe_cluster_id); | 831 size_t bytes_sent = TrySendRedundantPayloads(bytes, probe_cluster_id); |
866 if (bytes_sent < bytes) | 832 if (bytes_sent < bytes) |
867 bytes_sent += SendPadData(bytes - bytes_sent, probe_cluster_id); | 833 bytes_sent += SendPadData(bytes - bytes_sent, probe_cluster_id); |
868 return bytes_sent; | 834 return bytes_sent; |
869 } | 835 } |
870 | 836 |
871 bool RTPSender::SendToNetwork(uint8_t* buffer, | |
872 size_t payload_length, | |
873 size_t rtp_header_length, | |
874 int64_t capture_time_ms, | |
875 StorageType storage, | |
876 RtpPacketSender::Priority priority) { | |
877 size_t length = payload_length + rtp_header_length; | |
878 std::unique_ptr<RtpPacketToSend> packet( | |
879 new RtpPacketToSend(&rtp_header_extension_map_, length)); | |
880 RTC_CHECK(packet->Parse(buffer, length)); | |
881 packet->set_capture_time_ms(capture_time_ms); | |
882 return SendToNetwork(std::move(packet), storage, priority); | |
883 } | |
884 | |
885 bool RTPSender::SendToNetwork(std::unique_ptr<RtpPacketToSend> packet, | 837 bool RTPSender::SendToNetwork(std::unique_ptr<RtpPacketToSend> packet, |
886 StorageType storage, | 838 StorageType storage, |
887 RtpPacketSender::Priority priority) { | 839 RtpPacketSender::Priority priority) { |
888 RTC_DCHECK(packet); | 840 RTC_DCHECK(packet); |
889 int64_t now_ms = clock_->TimeInMilliseconds(); | 841 int64_t now_ms = clock_->TimeInMilliseconds(); |
890 | 842 |
891 // |capture_time_ms| <= 0 is considered invalid. | 843 // |capture_time_ms| <= 0 is considered invalid. |
892 // TODO(holmer): This should be changed all over Video Engine so that negative | 844 // TODO(holmer): This should be changed all over Video Engine so that negative |
893 // time is consider invalid, while 0 is considered a valid time. | 845 // time is consider invalid, while 0 is considered a valid time. |
894 if (packet->capture_time_ms() > 0) { | 846 if (packet->capture_time_ms() > 0) { |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1034 return first_allocated_sequence_number; | 986 return first_allocated_sequence_number; |
1035 } | 987 } |
1036 | 988 |
1037 void RTPSender::GetDataCounters(StreamDataCounters* rtp_stats, | 989 void RTPSender::GetDataCounters(StreamDataCounters* rtp_stats, |
1038 StreamDataCounters* rtx_stats) const { | 990 StreamDataCounters* rtx_stats) const { |
1039 rtc::CritScope lock(&statistics_crit_); | 991 rtc::CritScope lock(&statistics_crit_); |
1040 *rtp_stats = rtp_stats_; | 992 *rtp_stats = rtp_stats_; |
1041 *rtx_stats = rtx_rtp_stats_; | 993 *rtx_stats = rtx_rtp_stats_; |
1042 } | 994 } |
1043 | 995 |
1044 size_t RTPSender::CreateRtpHeader(uint8_t* header, | |
1045 int8_t payload_type, | |
1046 uint32_t ssrc, | |
1047 bool marker_bit, | |
1048 uint32_t timestamp, | |
1049 uint16_t sequence_number, | |
1050 const std::vector<uint32_t>& csrcs) const { | |
1051 header[0] = 0x80; // version 2. | |
1052 header[1] = static_cast<uint8_t>(payload_type); | |
1053 if (marker_bit) { | |
1054 header[1] |= kRtpMarkerBitMask; // Marker bit is set. | |
1055 } | |
1056 ByteWriter<uint16_t>::WriteBigEndian(header + 2, sequence_number); | |
1057 ByteWriter<uint32_t>::WriteBigEndian(header + 4, timestamp); | |
1058 ByteWriter<uint32_t>::WriteBigEndian(header + 8, ssrc); | |
1059 int32_t rtp_header_length = kRtpHeaderLength; | |
1060 | |
1061 if (csrcs.size() > 0) { | |
1062 uint8_t* ptr = &header[rtp_header_length]; | |
1063 for (size_t i = 0; i < csrcs.size(); ++i) { | |
1064 ByteWriter<uint32_t>::WriteBigEndian(ptr, csrcs[i]); | |
1065 ptr += 4; | |
1066 } | |
1067 header[0] = (header[0] & 0xf0) | csrcs.size(); | |
1068 | |
1069 // Update length of header. | |
1070 rtp_header_length += sizeof(uint32_t) * csrcs.size(); | |
1071 } | |
1072 | |
1073 uint16_t len = | |
1074 BuildRtpHeaderExtension(header + rtp_header_length, marker_bit); | |
1075 if (len > 0) { | |
1076 header[0] |= 0x10; // Set extension bit. | |
1077 rtp_header_length += len; | |
1078 } | |
1079 return rtp_header_length; | |
1080 } | |
1081 | |
1082 std::unique_ptr<RtpPacketToSend> RTPSender::AllocatePacket() const { | 996 std::unique_ptr<RtpPacketToSend> RTPSender::AllocatePacket() const { |
1083 rtc::CritScope lock(&send_critsect_); | 997 rtc::CritScope lock(&send_critsect_); |
1084 std::unique_ptr<RtpPacketToSend> packet( | 998 std::unique_ptr<RtpPacketToSend> packet( |
1085 new RtpPacketToSend(&rtp_header_extension_map_, max_payload_length_)); | 999 new RtpPacketToSend(&rtp_header_extension_map_, max_payload_length_)); |
1086 packet->SetSsrc(ssrc_); | 1000 packet->SetSsrc(ssrc_); |
1087 packet->SetCsrcs(csrcs_); | 1001 packet->SetCsrcs(csrcs_); |
1088 // Reserve extensions, if registered, RtpSender set in SendToNetwork. | 1002 // Reserve extensions, if registered, RtpSender set in SendToNetwork. |
1089 packet->ReserveExtension<AbsoluteSendTime>(); | 1003 packet->ReserveExtension<AbsoluteSendTime>(); |
1090 packet->ReserveExtension<TransmissionOffset>(); | 1004 packet->ReserveExtension<TransmissionOffset>(); |
1091 packet->ReserveExtension<TransportSequenceNumber>(); | 1005 packet->ReserveExtension<TransportSequenceNumber>(); |
(...skipping 14 matching lines...) Expand all Loading... |
1106 // Remember marker bit to determine if padding can be inserted with | 1020 // Remember marker bit to determine if padding can be inserted with |
1107 // sequence number following |packet|. | 1021 // sequence number following |packet|. |
1108 last_packet_marker_bit_ = packet->Marker(); | 1022 last_packet_marker_bit_ = packet->Marker(); |
1109 // Save timestamps to generate timestamp field and extensions for the padding. | 1023 // Save timestamps to generate timestamp field and extensions for the padding. |
1110 last_rtp_timestamp_ = packet->Timestamp(); | 1024 last_rtp_timestamp_ = packet->Timestamp(); |
1111 last_timestamp_time_ms_ = clock_->TimeInMilliseconds(); | 1025 last_timestamp_time_ms_ = clock_->TimeInMilliseconds(); |
1112 capture_time_ms_ = packet->capture_time_ms(); | 1026 capture_time_ms_ = packet->capture_time_ms(); |
1113 return true; | 1027 return true; |
1114 } | 1028 } |
1115 | 1029 |
1116 int32_t RTPSender::BuildRTPheader(uint8_t* data_buffer, | |
1117 int8_t payload_type, | |
1118 bool marker_bit, | |
1119 uint32_t capture_timestamp, | |
1120 int64_t capture_time_ms, | |
1121 bool timestamp_provided, | |
1122 bool inc_sequence_number) { | |
1123 return BuildRtpHeader(data_buffer, payload_type, marker_bit, | |
1124 capture_timestamp, capture_time_ms); | |
1125 } | |
1126 | |
1127 int32_t RTPSender::BuildRtpHeader(uint8_t* data_buffer, | |
1128 int8_t payload_type, | |
1129 bool marker_bit, | |
1130 uint32_t rtp_timestamp, | |
1131 int64_t capture_time_ms) { | |
1132 assert(payload_type >= 0); | |
1133 rtc::CritScope lock(&send_critsect_); | |
1134 if (!sending_media_) | |
1135 return -1; | |
1136 | |
1137 last_rtp_timestamp_ = rtp_timestamp; | |
1138 last_timestamp_time_ms_ = clock_->TimeInMilliseconds(); | |
1139 uint32_t sequence_number = sequence_number_++; | |
1140 capture_time_ms_ = capture_time_ms; | |
1141 last_packet_marker_bit_ = marker_bit; | |
1142 return CreateRtpHeader(data_buffer, payload_type, ssrc_, marker_bit, | |
1143 rtp_timestamp, sequence_number, csrcs_); | |
1144 } | |
1145 | |
1146 uint16_t RTPSender::BuildRtpHeaderExtension(uint8_t* data_buffer, | |
1147 bool marker_bit) const { | |
1148 if (rtp_header_extension_map_.Size() <= 0) { | |
1149 return 0; | |
1150 } | |
1151 // RTP header extension, RFC 3550. | |
1152 // 0 1 2 3 | |
1153 // 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 | |
1154 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
1155 // | defined by profile | length | | |
1156 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
1157 // | header extension | | |
1158 // | .... | | |
1159 // | |
1160 const uint32_t kPosLength = 2; | |
1161 const uint32_t kHeaderLength = kRtpOneByteHeaderLength; | |
1162 | |
1163 // Add extension ID (0xBEDE). | |
1164 ByteWriter<uint16_t>::WriteBigEndian(data_buffer, | |
1165 kRtpOneByteHeaderExtensionId); | |
1166 | |
1167 // Add extensions. | |
1168 uint16_t total_block_length = 0; | |
1169 | |
1170 RTPExtensionType type = rtp_header_extension_map_.First(); | |
1171 while (type != kRtpExtensionNone) { | |
1172 uint8_t block_length = 0; | |
1173 uint8_t* extension_data = &data_buffer[kHeaderLength + total_block_length]; | |
1174 switch (type) { | |
1175 case kRtpExtensionTransmissionTimeOffset: | |
1176 block_length = BuildTransmissionTimeOffsetExtension(extension_data); | |
1177 break; | |
1178 case kRtpExtensionAudioLevel: | |
1179 block_length = BuildAudioLevelExtension(extension_data); | |
1180 break; | |
1181 case kRtpExtensionAbsoluteSendTime: | |
1182 block_length = BuildAbsoluteSendTimeExtension(extension_data); | |
1183 break; | |
1184 case kRtpExtensionVideoRotation: | |
1185 block_length = BuildVideoRotationExtension(extension_data); | |
1186 break; | |
1187 case kRtpExtensionTransportSequenceNumber: | |
1188 block_length = BuildTransportSequenceNumberExtension( | |
1189 extension_data, transport_sequence_number_); | |
1190 break; | |
1191 case kRtpExtensionPlayoutDelay: { | |
1192 PlayoutDelay playout_delay = playout_delay_oracle_.playout_delay(); | |
1193 block_length = BuildPlayoutDelayExtension( | |
1194 extension_data, playout_delay.min_ms, playout_delay.max_ms); | |
1195 break; | |
1196 } | |
1197 default: | |
1198 assert(false); | |
1199 } | |
1200 total_block_length += block_length; | |
1201 type = rtp_header_extension_map_.Next(type); | |
1202 } | |
1203 if (total_block_length == 0) { | |
1204 // No extension added. | |
1205 return 0; | |
1206 } | |
1207 // Add padding elements until we've filled a 32 bit block. | |
1208 size_t padding_bytes = | |
1209 RtpUtility::Word32Align(total_block_length) - total_block_length; | |
1210 if (padding_bytes > 0) { | |
1211 memset(&data_buffer[kHeaderLength + total_block_length], 0, padding_bytes); | |
1212 total_block_length += padding_bytes; | |
1213 } | |
1214 // Set header length (in number of Word32, header excluded). | |
1215 ByteWriter<uint16_t>::WriteBigEndian(data_buffer + kPosLength, | |
1216 total_block_length / 4); | |
1217 // Total added length. | |
1218 return kHeaderLength + total_block_length; | |
1219 } | |
1220 | |
1221 uint8_t RTPSender::BuildTransmissionTimeOffsetExtension( | |
1222 uint8_t* data_buffer) const { | |
1223 // From RFC 5450: Transmission Time Offsets in RTP Streams. | |
1224 // | |
1225 // The transmission time is signaled to the receiver in-band using the | |
1226 // general mechanism for RTP header extensions [RFC5285]. The payload | |
1227 // of this extension (the transmitted value) is a 24-bit signed integer. | |
1228 // When added to the RTP timestamp of the packet, it represents the | |
1229 // "effective" RTP transmission time of the packet, on the RTP | |
1230 // timescale. | |
1231 // | |
1232 // The form of the transmission offset extension block: | |
1233 // | |
1234 // 0 1 2 3 | |
1235 // 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 | |
1236 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
1237 // | ID | len=2 | transmission offset | | |
1238 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
1239 | |
1240 // Get id defined by user. | |
1241 uint8_t id; | |
1242 if (rtp_header_extension_map_.GetId(kRtpExtensionTransmissionTimeOffset, | |
1243 &id) != 0) { | |
1244 // Not registered. | |
1245 return 0; | |
1246 } | |
1247 size_t pos = 0; | |
1248 const uint8_t len = 2; | |
1249 data_buffer[pos++] = (id << 4) + len; | |
1250 ByteWriter<int32_t, 3>::WriteBigEndian(data_buffer + pos, | |
1251 transmission_time_offset_); | |
1252 pos += 3; | |
1253 assert(pos == kTransmissionTimeOffsetLength); | |
1254 return kTransmissionTimeOffsetLength; | |
1255 } | |
1256 | |
1257 uint8_t RTPSender::BuildAudioLevelExtension(uint8_t* data_buffer) const { | |
1258 // An RTP Header Extension for Client-to-Mixer Audio Level Indication | |
1259 // | |
1260 // https://datatracker.ietf.org/doc/draft-lennox-avt-rtp-audio-level-exthdr/ | |
1261 // | |
1262 // The form of the audio level extension block: | |
1263 // | |
1264 // 0 1 | |
1265 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 | |
1266 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
1267 // | ID | len=0 |V| level | | |
1268 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
1269 // | |
1270 | |
1271 // Get id defined by user. | |
1272 uint8_t id; | |
1273 if (rtp_header_extension_map_.GetId(kRtpExtensionAudioLevel, &id) != 0) { | |
1274 // Not registered. | |
1275 return 0; | |
1276 } | |
1277 size_t pos = 0; | |
1278 const uint8_t len = 0; | |
1279 data_buffer[pos++] = (id << 4) + len; | |
1280 data_buffer[pos++] = (1 << 7) + 0; // Voice, 0 dBov. | |
1281 assert(pos == kAudioLevelLength); | |
1282 return kAudioLevelLength; | |
1283 } | |
1284 | |
1285 uint8_t RTPSender::BuildAbsoluteSendTimeExtension(uint8_t* data_buffer) const { | |
1286 // Absolute send time in RTP streams. | |
1287 // | |
1288 // The absolute send time is signaled to the receiver in-band using the | |
1289 // general mechanism for RTP header extensions [RFC5285]. The payload | |
1290 // of this extension (the transmitted value) is a 24-bit unsigned integer | |
1291 // containing the sender's current time in seconds as a fixed point number | |
1292 // with 18 bits fractional part. | |
1293 // | |
1294 // The form of the absolute send time extension block: | |
1295 // | |
1296 // 0 1 2 3 | |
1297 // 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 | |
1298 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
1299 // | ID | len=2 | absolute send time | | |
1300 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
1301 | |
1302 // Get id defined by user. | |
1303 uint8_t id; | |
1304 if (rtp_header_extension_map_.GetId(kRtpExtensionAbsoluteSendTime, | |
1305 &id) != 0) { | |
1306 // Not registered. | |
1307 return 0; | |
1308 } | |
1309 size_t pos = 0; | |
1310 const uint8_t len = 2; | |
1311 data_buffer[pos++] = (id << 4) + len; | |
1312 ByteWriter<uint32_t, 3>::WriteBigEndian(data_buffer + pos, | |
1313 absolute_send_time_); | |
1314 pos += 3; | |
1315 assert(pos == kAbsoluteSendTimeLength); | |
1316 return kAbsoluteSendTimeLength; | |
1317 } | |
1318 | |
1319 uint8_t RTPSender::BuildVideoRotationExtension(uint8_t* data_buffer) const { | |
1320 // Coordination of Video Orientation in RTP streams. | |
1321 // | |
1322 // Coordination of Video Orientation consists in signaling of the current | |
1323 // orientation of the image captured on the sender side to the receiver for | |
1324 // appropriate rendering and displaying. | |
1325 // | |
1326 // 0 1 | |
1327 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 | |
1328 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
1329 // | ID | len=0 |0 0 0 0 C F R R| | |
1330 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
1331 // | |
1332 | |
1333 // Get id defined by user. | |
1334 uint8_t id; | |
1335 if (rtp_header_extension_map_.GetId(kRtpExtensionVideoRotation, &id) != 0) { | |
1336 // Not registered. | |
1337 return 0; | |
1338 } | |
1339 size_t pos = 0; | |
1340 const uint8_t len = 0; | |
1341 data_buffer[pos++] = (id << 4) + len; | |
1342 data_buffer[pos++] = ConvertVideoRotationToCVOByte(rotation_); | |
1343 assert(pos == kVideoRotationLength); | |
1344 return kVideoRotationLength; | |
1345 } | |
1346 | |
1347 uint8_t RTPSender::BuildTransportSequenceNumberExtension( | |
1348 uint8_t* data_buffer, | |
1349 uint16_t sequence_number) const { | |
1350 // 0 1 2 | |
1351 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 | |
1352 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
1353 // | ID | L=1 |transport wide sequence number | | |
1354 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
1355 | |
1356 // Get id defined by user. | |
1357 uint8_t id; | |
1358 if (rtp_header_extension_map_.GetId(kRtpExtensionTransportSequenceNumber, | |
1359 &id) != 0) { | |
1360 // Not registered. | |
1361 return 0; | |
1362 } | |
1363 size_t pos = 0; | |
1364 const uint8_t len = 1; | |
1365 data_buffer[pos++] = (id << 4) + len; | |
1366 ByteWriter<uint16_t>::WriteBigEndian(data_buffer + pos, sequence_number); | |
1367 pos += 2; | |
1368 assert(pos == kTransportSequenceNumberLength); | |
1369 return kTransportSequenceNumberLength; | |
1370 } | |
1371 | |
1372 uint8_t RTPSender::BuildPlayoutDelayExtension( | |
1373 uint8_t* data_buffer, | |
1374 uint16_t min_playout_delay_ms, | |
1375 uint16_t max_playout_delay_ms) const { | |
1376 RTC_DCHECK_LE(min_playout_delay_ms, kPlayoutDelayMaxMs); | |
1377 RTC_DCHECK_LE(max_playout_delay_ms, kPlayoutDelayMaxMs); | |
1378 RTC_DCHECK_LE(min_playout_delay_ms, max_playout_delay_ms); | |
1379 // 0 1 2 3 | |
1380 // 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 | |
1381 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
1382 // | ID | len=2 | MIN delay | MAX delay | | |
1383 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
1384 uint8_t id; | |
1385 if (rtp_header_extension_map_.GetId(kRtpExtensionPlayoutDelay, &id) != 0) { | |
1386 // Not registered. | |
1387 return 0; | |
1388 } | |
1389 size_t pos = 0; | |
1390 const uint8_t len = 2; | |
1391 // Convert MS to value to be sent on extension header. | |
1392 uint16_t min_playout = min_playout_delay_ms / kPlayoutDelayGranularityMs; | |
1393 uint16_t max_playout = max_playout_delay_ms / kPlayoutDelayGranularityMs; | |
1394 | |
1395 data_buffer[pos++] = (id << 4) + len; | |
1396 data_buffer[pos++] = min_playout >> 4; | |
1397 data_buffer[pos++] = ((min_playout & 0xf) << 4) | (max_playout >> 8); | |
1398 data_buffer[pos++] = max_playout & 0xff; | |
1399 assert(pos == kPlayoutDelayLength); | |
1400 return kPlayoutDelayLength; | |
1401 } | |
1402 | |
1403 bool RTPSender::FindHeaderExtensionPosition(RTPExtensionType type, | 1030 bool RTPSender::FindHeaderExtensionPosition(RTPExtensionType type, |
1404 const uint8_t* rtp_packet, | 1031 const uint8_t* rtp_packet, |
1405 size_t rtp_packet_length, | 1032 size_t rtp_packet_length, |
1406 const RTPHeader& rtp_header, | 1033 const RTPHeader& rtp_header, |
1407 size_t* position) const { | 1034 size_t* position) const { |
1408 // Get length until start of header extension block. | 1035 // Get length until start of header extension block. |
1409 int extension_block_pos = | 1036 int extension_block_pos = |
1410 rtp_header_extension_map_.GetLengthUntilBlockStartInBytes(type); | 1037 rtp_header_extension_map_.GetLengthUntilBlockStartInBytes(type); |
1411 if (extension_block_pos < 0) { | 1038 if (extension_block_pos < 0) { |
1412 LOG(LS_WARNING) << "Failed to find extension position for " << type | 1039 LOG(LS_WARNING) << "Failed to find extension position for " << type |
(...skipping 18 matching lines...) Expand all Loading... |
1431 rtp_packet[extension_pos + 1] == 0xDE)) { | 1058 rtp_packet[extension_pos + 1] == 0xDE)) { |
1432 LOG(LS_WARNING) << "Failed to find extension position for " << type | 1059 LOG(LS_WARNING) << "Failed to find extension position for " << type |
1433 << "as hdr extension not found."; | 1060 << "as hdr extension not found."; |
1434 return false; | 1061 return false; |
1435 } | 1062 } |
1436 | 1063 |
1437 *position = block_pos; | 1064 *position = block_pos; |
1438 return true; | 1065 return true; |
1439 } | 1066 } |
1440 | 1067 |
1441 RTPSender::ExtensionStatus RTPSender::VerifyExtension( | |
1442 RTPExtensionType extension_type, | |
1443 uint8_t* rtp_packet, | |
1444 size_t rtp_packet_length, | |
1445 const RTPHeader& rtp_header, | |
1446 size_t extension_length_bytes, | |
1447 size_t* extension_offset) const { | |
1448 // Get id. | |
1449 uint8_t id = 0; | |
1450 if (rtp_header_extension_map_.GetId(extension_type, &id) != 0) | |
1451 return ExtensionStatus::kNotRegistered; | |
1452 | |
1453 size_t block_pos = 0; | |
1454 if (!FindHeaderExtensionPosition(extension_type, rtp_packet, | |
1455 rtp_packet_length, rtp_header, &block_pos)) | |
1456 return ExtensionStatus::kError; | |
1457 | |
1458 // Verify first byte in block. | |
1459 const uint8_t first_block_byte = (id << 4) + (extension_length_bytes - 2); | |
1460 if (rtp_packet[block_pos] != first_block_byte) | |
1461 return ExtensionStatus::kError; | |
1462 | |
1463 *extension_offset = block_pos; | |
1464 return ExtensionStatus::kOk; | |
1465 } | |
1466 | |
1467 bool RTPSender::UpdateAudioLevel(uint8_t* rtp_packet, | |
1468 size_t rtp_packet_length, | |
1469 const RTPHeader& rtp_header, | |
1470 bool is_voiced, | |
1471 uint8_t dBov) const { | |
1472 size_t offset; | |
1473 rtc::CritScope lock(&send_critsect_); | |
1474 | |
1475 switch (VerifyExtension(kRtpExtensionAudioLevel, rtp_packet, | |
1476 rtp_packet_length, rtp_header, kAudioLevelLength, | |
1477 &offset)) { | |
1478 case ExtensionStatus::kNotRegistered: | |
1479 return false; | |
1480 case ExtensionStatus::kError: | |
1481 LOG(LS_WARNING) << "Failed to update audio level."; | |
1482 return false; | |
1483 case ExtensionStatus::kOk: | |
1484 break; | |
1485 default: | |
1486 RTC_NOTREACHED(); | |
1487 } | |
1488 | |
1489 rtp_packet[offset + 1] = (is_voiced ? 0x80 : 0x00) + (dBov & 0x7f); | |
1490 return true; | |
1491 } | |
1492 | |
1493 bool RTPSender::UpdateVideoRotation(uint8_t* rtp_packet, | |
1494 size_t rtp_packet_length, | |
1495 const RTPHeader& rtp_header, | |
1496 VideoRotation rotation) const { | |
1497 size_t offset; | |
1498 rtc::CritScope lock(&send_critsect_); | |
1499 | |
1500 switch (VerifyExtension(kRtpExtensionVideoRotation, rtp_packet, | |
1501 rtp_packet_length, rtp_header, kVideoRotationLength, | |
1502 &offset)) { | |
1503 case ExtensionStatus::kNotRegistered: | |
1504 return false; | |
1505 case ExtensionStatus::kError: | |
1506 LOG(LS_WARNING) << "Failed to update CVO."; | |
1507 return false; | |
1508 case ExtensionStatus::kOk: | |
1509 break; | |
1510 default: | |
1511 RTC_NOTREACHED(); | |
1512 } | |
1513 | |
1514 rtp_packet[offset + 1] = ConvertVideoRotationToCVOByte(rotation); | |
1515 return true; | |
1516 } | |
1517 | |
1518 bool RTPSender::UpdateTransportSequenceNumber(RtpPacketToSend* packet, | 1068 bool RTPSender::UpdateTransportSequenceNumber(RtpPacketToSend* packet, |
1519 int* packet_id) const { | 1069 int* packet_id) const { |
1520 RTC_DCHECK(packet); | 1070 RTC_DCHECK(packet); |
1521 RTC_DCHECK(packet_id); | 1071 RTC_DCHECK(packet_id); |
1522 rtc::CritScope lock(&send_critsect_); | 1072 rtc::CritScope lock(&send_critsect_); |
1523 if (!rtp_header_extension_map_.IsRegistered(TransportSequenceNumber::kId)) | 1073 if (!rtp_header_extension_map_.IsRegistered(TransportSequenceNumber::kId)) |
1524 return false; | 1074 return false; |
1525 | 1075 |
1526 if (!transport_sequence_number_allocator_) | 1076 if (!transport_sequence_number_allocator_) |
1527 return false; | 1077 return false; |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1763 rtc::CritScope lock(&send_critsect_); | 1313 rtc::CritScope lock(&send_critsect_); |
1764 | 1314 |
1765 RtpState state; | 1315 RtpState state; |
1766 state.sequence_number = sequence_number_rtx_; | 1316 state.sequence_number = sequence_number_rtx_; |
1767 state.start_timestamp = timestamp_offset_; | 1317 state.start_timestamp = timestamp_offset_; |
1768 | 1318 |
1769 return state; | 1319 return state; |
1770 } | 1320 } |
1771 | 1321 |
1772 } // namespace webrtc | 1322 } // namespace webrtc |
OLD | NEW |