OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 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 |
11 #include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h" | 11 #include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h" |
12 | 12 |
13 #include "webrtc/base/logging.h" | 13 #include "webrtc/base/logging.h" |
14 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | 14 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" |
15 | 15 |
16 namespace webrtc { | 16 namespace webrtc { |
17 | 17 |
18 RTPPayloadRegistry::RTPPayloadRegistry(RTPPayloadStrategy* rtp_payload_strategy) | 18 RTPPayloadRegistry::RTPPayloadRegistry(RTPPayloadStrategy* rtp_payload_strategy) |
19 : crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), | 19 : rtp_payload_strategy_(rtp_payload_strategy), |
20 rtp_payload_strategy_(rtp_payload_strategy), | |
21 red_payload_type_(-1), | 20 red_payload_type_(-1), |
22 ulpfec_payload_type_(-1), | 21 ulpfec_payload_type_(-1), |
23 incoming_payload_type_(-1), | 22 incoming_payload_type_(-1), |
24 last_received_payload_type_(-1), | 23 last_received_payload_type_(-1), |
25 last_received_media_payload_type_(-1), | 24 last_received_media_payload_type_(-1), |
26 rtx_(false), | 25 rtx_(false), |
27 rtx_payload_type_(-1), | 26 rtx_payload_type_(-1), |
28 ssrc_rtx_(0) {} | 27 ssrc_rtx_(0) {} |
29 | 28 |
30 RTPPayloadRegistry::~RTPPayloadRegistry() { | 29 RTPPayloadRegistry::~RTPPayloadRegistry() { |
(...skipping 29 matching lines...) Expand all Loading... |
60 case 79: // 207 Extended report. | 59 case 79: // 207 Extended report. |
61 LOG(LS_ERROR) << "Can't register invalid receiver payload type: " | 60 LOG(LS_ERROR) << "Can't register invalid receiver payload type: " |
62 << payload_type; | 61 << payload_type; |
63 return -1; | 62 return -1; |
64 default: | 63 default: |
65 break; | 64 break; |
66 } | 65 } |
67 | 66 |
68 size_t payload_name_length = strlen(payload_name); | 67 size_t payload_name_length = strlen(payload_name); |
69 | 68 |
70 CriticalSectionScoped cs(crit_sect_.get()); | 69 rtc::CritScope cs(&crit_sect_); |
71 | 70 |
72 RtpUtility::PayloadTypeMap::iterator it = | 71 RtpUtility::PayloadTypeMap::iterator it = |
73 payload_type_map_.find(payload_type); | 72 payload_type_map_.find(payload_type); |
74 | 73 |
75 if (it != payload_type_map_.end()) { | 74 if (it != payload_type_map_.end()) { |
76 // We already use this payload type. | 75 // We already use this payload type. |
77 RtpUtility::Payload* payload = it->second; | 76 RtpUtility::Payload* payload = it->second; |
78 | 77 |
79 assert(payload); | 78 assert(payload); |
80 | 79 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 | 114 |
116 // Successful set of payload type, clear the value of last received payload | 115 // Successful set of payload type, clear the value of last received payload |
117 // type since it might mean something else. | 116 // type since it might mean something else. |
118 last_received_payload_type_ = -1; | 117 last_received_payload_type_ = -1; |
119 last_received_media_payload_type_ = -1; | 118 last_received_media_payload_type_ = -1; |
120 return 0; | 119 return 0; |
121 } | 120 } |
122 | 121 |
123 int32_t RTPPayloadRegistry::DeRegisterReceivePayload( | 122 int32_t RTPPayloadRegistry::DeRegisterReceivePayload( |
124 const int8_t payload_type) { | 123 const int8_t payload_type) { |
125 CriticalSectionScoped cs(crit_sect_.get()); | 124 rtc::CritScope cs(&crit_sect_); |
126 RtpUtility::PayloadTypeMap::iterator it = | 125 RtpUtility::PayloadTypeMap::iterator it = |
127 payload_type_map_.find(payload_type); | 126 payload_type_map_.find(payload_type); |
128 assert(it != payload_type_map_.end()); | 127 assert(it != payload_type_map_.end()); |
129 delete it->second; | 128 delete it->second; |
130 payload_type_map_.erase(it); | 129 payload_type_map_.erase(it); |
131 return 0; | 130 return 0; |
132 } | 131 } |
133 | 132 |
134 // There can't be several codecs with the same rate, frequency and channels | 133 // There can't be several codecs with the same rate, frequency and channels |
135 // for audio codecs, but there can for video. | 134 // for audio codecs, but there can for video. |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 | 168 |
170 int32_t RTPPayloadRegistry::ReceivePayloadType( | 169 int32_t RTPPayloadRegistry::ReceivePayloadType( |
171 const char payload_name[RTP_PAYLOAD_NAME_SIZE], | 170 const char payload_name[RTP_PAYLOAD_NAME_SIZE], |
172 const uint32_t frequency, | 171 const uint32_t frequency, |
173 const size_t channels, | 172 const size_t channels, |
174 const uint32_t rate, | 173 const uint32_t rate, |
175 int8_t* payload_type) const { | 174 int8_t* payload_type) const { |
176 assert(payload_type); | 175 assert(payload_type); |
177 size_t payload_name_length = strlen(payload_name); | 176 size_t payload_name_length = strlen(payload_name); |
178 | 177 |
179 CriticalSectionScoped cs(crit_sect_.get()); | 178 rtc::CritScope cs(&crit_sect_); |
180 | 179 |
181 RtpUtility::PayloadTypeMap::const_iterator it = payload_type_map_.begin(); | 180 RtpUtility::PayloadTypeMap::const_iterator it = payload_type_map_.begin(); |
182 | 181 |
183 for (; it != payload_type_map_.end(); ++it) { | 182 for (; it != payload_type_map_.end(); ++it) { |
184 RtpUtility::Payload* payload = it->second; | 183 RtpUtility::Payload* payload = it->second; |
185 assert(payload); | 184 assert(payload); |
186 | 185 |
187 size_t name_length = strlen(payload->name); | 186 size_t name_length = strlen(payload->name); |
188 if (payload_name_length == name_length && | 187 if (payload_name_length == name_length && |
189 RtpUtility::StringCompare( | 188 RtpUtility::StringCompare( |
(...skipping 21 matching lines...) Expand all Loading... |
211 // Video. | 210 // Video. |
212 *payload_type = it->first; | 211 *payload_type = it->first; |
213 return 0; | 212 return 0; |
214 } | 213 } |
215 } | 214 } |
216 } | 215 } |
217 return -1; | 216 return -1; |
218 } | 217 } |
219 | 218 |
220 bool RTPPayloadRegistry::RtxEnabled() const { | 219 bool RTPPayloadRegistry::RtxEnabled() const { |
221 CriticalSectionScoped cs(crit_sect_.get()); | 220 rtc::CritScope cs(&crit_sect_); |
222 return rtx_; | 221 return rtx_; |
223 } | 222 } |
224 | 223 |
225 bool RTPPayloadRegistry::IsRtx(const RTPHeader& header) const { | 224 bool RTPPayloadRegistry::IsRtx(const RTPHeader& header) const { |
226 CriticalSectionScoped cs(crit_sect_.get()); | 225 rtc::CritScope cs(&crit_sect_); |
227 return IsRtxInternal(header); | 226 return IsRtxInternal(header); |
228 } | 227 } |
229 | 228 |
230 bool RTPPayloadRegistry::IsRtxInternal(const RTPHeader& header) const { | 229 bool RTPPayloadRegistry::IsRtxInternal(const RTPHeader& header) const { |
231 return rtx_ && ssrc_rtx_ == header.ssrc; | 230 return rtx_ && ssrc_rtx_ == header.ssrc; |
232 } | 231 } |
233 | 232 |
234 bool RTPPayloadRegistry::RestoreOriginalPacket(uint8_t** restored_packet, | 233 bool RTPPayloadRegistry::RestoreOriginalPacket(uint8_t** restored_packet, |
235 const uint8_t* packet, | 234 const uint8_t* packet, |
236 size_t* packet_length, | 235 size_t* packet_length, |
(...skipping 20 matching lines...) Expand all Loading... |
257 memcpy(restored_packet + header.headerLength, | 256 memcpy(restored_packet + header.headerLength, |
258 packet + header.headerLength + kRtxHeaderSize, | 257 packet + header.headerLength + kRtxHeaderSize, |
259 *packet_length - header.headerLength - kRtxHeaderSize); | 258 *packet_length - header.headerLength - kRtxHeaderSize); |
260 *packet_length -= kRtxHeaderSize; | 259 *packet_length -= kRtxHeaderSize; |
261 | 260 |
262 // Replace the SSRC and the sequence number with the originals. | 261 // Replace the SSRC and the sequence number with the originals. |
263 ByteWriter<uint16_t>::WriteBigEndian(restored_packet + 2, | 262 ByteWriter<uint16_t>::WriteBigEndian(restored_packet + 2, |
264 original_sequence_number); | 263 original_sequence_number); |
265 ByteWriter<uint32_t>::WriteBigEndian(restored_packet + 8, original_ssrc); | 264 ByteWriter<uint32_t>::WriteBigEndian(restored_packet + 8, original_ssrc); |
266 | 265 |
267 CriticalSectionScoped cs(crit_sect_.get()); | 266 rtc::CritScope cs(&crit_sect_); |
268 if (!rtx_) | 267 if (!rtx_) |
269 return true; | 268 return true; |
270 | 269 |
271 int associated_payload_type; | 270 int associated_payload_type; |
272 auto apt_mapping = rtx_payload_type_map_.find(header.payloadType); | 271 auto apt_mapping = rtx_payload_type_map_.find(header.payloadType); |
273 if (apt_mapping == rtx_payload_type_map_.end()) | 272 if (apt_mapping == rtx_payload_type_map_.end()) |
274 return false; | 273 return false; |
275 associated_payload_type = apt_mapping->second; | 274 associated_payload_type = apt_mapping->second; |
276 if (red_payload_type_ != -1) { | 275 if (red_payload_type_ != -1) { |
277 // Assume red will be used if it's configured. | 276 // Assume red will be used if it's configured. |
278 // This is a workaround for a Chrome sdp bug where rtx is associated | 277 // This is a workaround for a Chrome sdp bug where rtx is associated |
279 // with the media codec even though media is sent over red. | 278 // with the media codec even though media is sent over red. |
280 // TODO(holmer): Remove once the Chrome versions exposing this bug are | 279 // TODO(holmer): Remove once the Chrome versions exposing this bug are |
281 // old enough, which should be once Chrome Stable reaches M53 as this | 280 // old enough, which should be once Chrome Stable reaches M53 as this |
282 // work-around went into M50. | 281 // work-around went into M50. |
283 associated_payload_type = red_payload_type_; | 282 associated_payload_type = red_payload_type_; |
284 } | 283 } |
285 restored_packet[1] = static_cast<uint8_t>(associated_payload_type); | 284 restored_packet[1] = static_cast<uint8_t>(associated_payload_type); |
286 if (header.markerBit) { | 285 if (header.markerBit) { |
287 restored_packet[1] |= kRtpMarkerBitMask; // Marker bit is set. | 286 restored_packet[1] |= kRtpMarkerBitMask; // Marker bit is set. |
288 } | 287 } |
289 return true; | 288 return true; |
290 } | 289 } |
291 | 290 |
292 void RTPPayloadRegistry::SetRtxSsrc(uint32_t ssrc) { | 291 void RTPPayloadRegistry::SetRtxSsrc(uint32_t ssrc) { |
293 CriticalSectionScoped cs(crit_sect_.get()); | 292 rtc::CritScope cs(&crit_sect_); |
294 ssrc_rtx_ = ssrc; | 293 ssrc_rtx_ = ssrc; |
295 rtx_ = true; | 294 rtx_ = true; |
296 } | 295 } |
297 | 296 |
298 bool RTPPayloadRegistry::GetRtxSsrc(uint32_t* ssrc) const { | 297 bool RTPPayloadRegistry::GetRtxSsrc(uint32_t* ssrc) const { |
299 CriticalSectionScoped cs(crit_sect_.get()); | 298 rtc::CritScope cs(&crit_sect_); |
300 *ssrc = ssrc_rtx_; | 299 *ssrc = ssrc_rtx_; |
301 return rtx_; | 300 return rtx_; |
302 } | 301 } |
303 | 302 |
304 void RTPPayloadRegistry::SetRtxPayloadType(int payload_type, | 303 void RTPPayloadRegistry::SetRtxPayloadType(int payload_type, |
305 int associated_payload_type) { | 304 int associated_payload_type) { |
306 CriticalSectionScoped cs(crit_sect_.get()); | 305 rtc::CritScope cs(&crit_sect_); |
307 if (payload_type < 0) { | 306 if (payload_type < 0) { |
308 LOG(LS_ERROR) << "Invalid RTX payload type: " << payload_type; | 307 LOG(LS_ERROR) << "Invalid RTX payload type: " << payload_type; |
309 return; | 308 return; |
310 } | 309 } |
311 | 310 |
312 rtx_payload_type_map_[payload_type] = associated_payload_type; | 311 rtx_payload_type_map_[payload_type] = associated_payload_type; |
313 rtx_ = true; | 312 rtx_ = true; |
314 rtx_payload_type_ = payload_type; | 313 rtx_payload_type_ = payload_type; |
315 } | 314 } |
316 | 315 |
317 bool RTPPayloadRegistry::IsRed(const RTPHeader& header) const { | 316 bool RTPPayloadRegistry::IsRed(const RTPHeader& header) const { |
318 CriticalSectionScoped cs(crit_sect_.get()); | 317 rtc::CritScope cs(&crit_sect_); |
319 return red_payload_type_ == header.payloadType; | 318 return red_payload_type_ == header.payloadType; |
320 } | 319 } |
321 | 320 |
322 bool RTPPayloadRegistry::IsEncapsulated(const RTPHeader& header) const { | 321 bool RTPPayloadRegistry::IsEncapsulated(const RTPHeader& header) const { |
323 return IsRed(header) || IsRtx(header); | 322 return IsRed(header) || IsRtx(header); |
324 } | 323 } |
325 | 324 |
326 bool RTPPayloadRegistry::GetPayloadSpecifics(uint8_t payload_type, | 325 bool RTPPayloadRegistry::GetPayloadSpecifics(uint8_t payload_type, |
327 PayloadUnion* payload) const { | 326 PayloadUnion* payload) const { |
328 CriticalSectionScoped cs(crit_sect_.get()); | 327 rtc::CritScope cs(&crit_sect_); |
329 RtpUtility::PayloadTypeMap::const_iterator it = | 328 RtpUtility::PayloadTypeMap::const_iterator it = |
330 payload_type_map_.find(payload_type); | 329 payload_type_map_.find(payload_type); |
331 | 330 |
332 // Check that this is a registered payload type. | 331 // Check that this is a registered payload type. |
333 if (it == payload_type_map_.end()) { | 332 if (it == payload_type_map_.end()) { |
334 return false; | 333 return false; |
335 } | 334 } |
336 *payload = it->second->typeSpecific; | 335 *payload = it->second->typeSpecific; |
337 return true; | 336 return true; |
338 } | 337 } |
339 | 338 |
340 int RTPPayloadRegistry::GetPayloadTypeFrequency( | 339 int RTPPayloadRegistry::GetPayloadTypeFrequency( |
341 uint8_t payload_type) const { | 340 uint8_t payload_type) const { |
342 const RtpUtility::Payload* payload = PayloadTypeToPayload(payload_type); | 341 const RtpUtility::Payload* payload = PayloadTypeToPayload(payload_type); |
343 if (!payload) { | 342 if (!payload) { |
344 return -1; | 343 return -1; |
345 } | 344 } |
346 CriticalSectionScoped cs(crit_sect_.get()); | 345 rtc::CritScope cs(&crit_sect_); |
347 return rtp_payload_strategy_->GetPayloadTypeFrequency(*payload); | 346 return rtp_payload_strategy_->GetPayloadTypeFrequency(*payload); |
348 } | 347 } |
349 | 348 |
350 const RtpUtility::Payload* RTPPayloadRegistry::PayloadTypeToPayload( | 349 const RtpUtility::Payload* RTPPayloadRegistry::PayloadTypeToPayload( |
351 uint8_t payload_type) const { | 350 uint8_t payload_type) const { |
352 CriticalSectionScoped cs(crit_sect_.get()); | 351 rtc::CritScope cs(&crit_sect_); |
353 | 352 |
354 RtpUtility::PayloadTypeMap::const_iterator it = | 353 RtpUtility::PayloadTypeMap::const_iterator it = |
355 payload_type_map_.find(payload_type); | 354 payload_type_map_.find(payload_type); |
356 | 355 |
357 // Check that this is a registered payload type. | 356 // Check that this is a registered payload type. |
358 if (it == payload_type_map_.end()) { | 357 if (it == payload_type_map_.end()) { |
359 return nullptr; | 358 return nullptr; |
360 } | 359 } |
361 | 360 |
362 return it->second; | 361 return it->second; |
363 } | 362 } |
364 | 363 |
365 void RTPPayloadRegistry::SetIncomingPayloadType(const RTPHeader& header) { | 364 void RTPPayloadRegistry::SetIncomingPayloadType(const RTPHeader& header) { |
366 CriticalSectionScoped cs(crit_sect_.get()); | 365 rtc::CritScope cs(&crit_sect_); |
367 if (!IsRtxInternal(header)) | 366 if (!IsRtxInternal(header)) |
368 incoming_payload_type_ = header.payloadType; | 367 incoming_payload_type_ = header.payloadType; |
369 } | 368 } |
370 | 369 |
371 bool RTPPayloadRegistry::ReportMediaPayloadType(uint8_t media_payload_type) { | 370 bool RTPPayloadRegistry::ReportMediaPayloadType(uint8_t media_payload_type) { |
372 CriticalSectionScoped cs(crit_sect_.get()); | 371 rtc::CritScope cs(&crit_sect_); |
373 if (last_received_media_payload_type_ == media_payload_type) { | 372 if (last_received_media_payload_type_ == media_payload_type) { |
374 // Media type unchanged. | 373 // Media type unchanged. |
375 return true; | 374 return true; |
376 } | 375 } |
377 last_received_media_payload_type_ = media_payload_type; | 376 last_received_media_payload_type_ = media_payload_type; |
378 return false; | 377 return false; |
379 } | 378 } |
380 | 379 |
381 class RTPPayloadAudioStrategy : public RTPPayloadStrategy { | 380 class RTPPayloadAudioStrategy : public RTPPayloadStrategy { |
382 public: | 381 public: |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 RTPPayloadStrategy* RTPPayloadStrategy::CreateStrategy( | 473 RTPPayloadStrategy* RTPPayloadStrategy::CreateStrategy( |
475 const bool handling_audio) { | 474 const bool handling_audio) { |
476 if (handling_audio) { | 475 if (handling_audio) { |
477 return new RTPPayloadAudioStrategy(); | 476 return new RTPPayloadAudioStrategy(); |
478 } else { | 477 } else { |
479 return new RTPPayloadVideoStrategy(); | 478 return new RTPPayloadVideoStrategy(); |
480 } | 479 } |
481 } | 480 } |
482 | 481 |
483 } // namespace webrtc | 482 } // namespace webrtc |
OLD | NEW |