| 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 |