1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 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 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.h" 12 13 #include <assert.h> 14 #include <math.h> 15 #include <stdlib.h> 16 #include <string.h> 17 18 #include "webrtc/base/logging.h" 19 #include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h" 20 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" 21 #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h" 22 23 namespace webrtc { 24 25 using RtpUtility::Payload; 26 using RtpUtility::StringCompare; 27 28 RtpReceiver* RtpReceiver::CreateVideoReceiver( 29 Clock* clock, 30 RtpData* incoming_payload_callback, 31 RtpFeedback* incoming_messages_callback, 32 RTPPayloadRegistry* rtp_payload_registry) { 33 if (!incoming_payload_callback) 34 incoming_payload_callback = NullObjectRtpData(); 35 if (!incoming_messages_callback) 36 incoming_messages_callback = NullObjectRtpFeedback(); 37 return new RtpReceiverImpl( 38 clock, NullObjectRtpAudioFeedback(), incoming_messages_callback, 39 rtp_payload_registry, 40 RTPReceiverStrategy::CreateVideoStrategy(incoming_payload_callback)); 41 } 42 43 RtpReceiver* RtpReceiver::CreateAudioReceiver( 44 Clock* clock, 45 RtpAudioFeedback* incoming_audio_feedback, 46 RtpData* incoming_payload_callback, 47 RtpFeedback* incoming_messages_callback, 48 RTPPayloadRegistry* rtp_payload_registry) { 49 if (!incoming_audio_feedback) 50 incoming_audio_feedback = NullObjectRtpAudioFeedback(); 51 if (!incoming_payload_callback) 52 incoming_payload_callback = NullObjectRtpData(); 53 if (!incoming_messages_callback) 54 incoming_messages_callback = NullObjectRtpFeedback(); 55 return new RtpReceiverImpl( 56 clock, incoming_audio_feedback, incoming_messages_callback, 57 rtp_payload_registry, 58 RTPReceiverStrategy::CreateAudioStrategy(incoming_payload_callback, 59 incoming_audio_feedback)); 60 } 61 62 RtpReceiverImpl::RtpReceiverImpl( 63 Clock* clock, 64 RtpAudioFeedback* incoming_audio_messages_callback, 65 RtpFeedback* incoming_messages_callback, 66 RTPPayloadRegistry* rtp_payload_registry, 67 RTPReceiverStrategy* rtp_media_receiver) 68 : clock_(clock), 69 rtp_payload_registry_(rtp_payload_registry), 70 rtp_media_receiver_(rtp_media_receiver), 71 cb_rtp_feedback_(incoming_messages_callback), 72 critical_section_rtp_receiver_( 73 CriticalSectionWrapper::CreateCriticalSection()), 74 last_receive_time_(0), 75 last_received_payload_length_(0), 76 ssrc_(0), 77 num_csrcs_(0), 78 current_remote_csrc_(), 79 last_received_timestamp_(0), 80 last_received_frame_time_ms_(-1), 81 last_received_sequence_number_(0), 82 nack_method_(kNackOff) { 83 assert(incoming_audio_messages_callback); 84 assert(incoming_messages_callback); 85 86 memset(current_remote_csrc_, 0, sizeof(current_remote_csrc_)); 87 } 88 89 RtpReceiverImpl::~RtpReceiverImpl() { 90 for (int i = 0; i < num_csrcs_; ++i) { 91 cb_rtp_feedback_->OnIncomingCSRCChanged(current_remote_csrc_[i], false); 92 } 93 } 94 95 int32_t RtpReceiverImpl::RegisterReceivePayload( 96 const char payload_name[RTP_PAYLOAD_NAME_SIZE], 97 const int8_t payload_type, 98 const uint32_t frequency, 99 const size_t channels, 100 const uint32_t rate) { 101 CriticalSectionScoped lock(critical_section_rtp_receiver_.get()); 102 103 // TODO(phoglund): Try to streamline handling of the RED codec and some other 104 // cases which makes it necessary to keep track of whether we created a 105 // payload or not. 106 bool created_new_payload = false; 107 int32_t result = rtp_payload_registry_->RegisterReceivePayload( 108 payload_name, payload_type, frequency, channels, rate, 109 &created_new_payload); 110 if (created_new_payload) { 111 if (rtp_media_receiver_->OnNewPayloadTypeCreated(payload_name, payload_type, 112 frequency) != 0) { 113 LOG(LS_ERROR) << "Failed to register payload: " << payload_name << "/" 114 << static_cast<int>(payload_type); 115 return -1; 116 } 117 } 118 return result; 119 } 120 121 int32_t RtpReceiverImpl::DeRegisterReceivePayload( 122 const int8_t payload_type) { 123 CriticalSectionScoped lock(critical_section_rtp_receiver_.get()); 124 return rtp_payload_registry_->DeRegisterReceivePayload(payload_type); 125 } 126 127 NACKMethod RtpReceiverImpl::NACK() const { 128 CriticalSectionScoped lock(critical_section_rtp_receiver_.get()); 129 return nack_method_; 130 } 131 132 // Turn negative acknowledgment requests on/off. 133 void RtpReceiverImpl::SetNACKStatus(const NACKMethod method) { 134 CriticalSectionScoped lock(critical_section_rtp_receiver_.get()); 135 nack_method_ = method; 136 } 137 138 uint32_t RtpReceiverImpl::SSRC() const { 139 CriticalSectionScoped lock(critical_section_rtp_receiver_.get()); 140 return ssrc_; 141 } 142 143 // Get remote CSRC. 144 int32_t RtpReceiverImpl::CSRCs(uint32_t array_of_csrcs[kRtpCsrcSize]) const { 145 CriticalSectionScoped lock(critical_section_rtp_receiver_.get()); 146 147 assert(num_csrcs_ <= kRtpCsrcSize); 148 149 if (num_csrcs_ > 0) { 150 memcpy(array_of_csrcs, current_remote_csrc_, sizeof(uint32_t)*num_csrcs_); 151 } 152 return num_csrcs_; 153 } 154 155 int32_t RtpReceiverImpl::Energy( 156 uint8_t array_of_energy[kRtpCsrcSize]) const { 157 return rtp_media_receiver_->Energy(array_of_energy); 158 } 159 160 bool RtpReceiverImpl::IncomingRtpPacket( 161 const RTPHeader& rtp_header, 162 const uint8_t* payload, 163 size_t payload_length, 164 PayloadUnion payload_specific, 165 bool in_order) { 166 // Trigger our callbacks. 167 CheckSSRCChanged(rtp_header); 168 169 int8_t first_payload_byte = payload_length > 0 ? payload[0] : 0; 170 bool is_red = false; 171 172 if (CheckPayloadChanged(rtp_header, first_payload_byte, &is_red, 173 &payload_specific) == -1) { 174 if (payload_length == 0) { 175 // OK, keep-alive packet. 176 return true; 177 } 178 LOG(LS_WARNING) << "Receiving invalid payload type."; 179 return false; 180 } 181 182 WebRtcRTPHeader webrtc_rtp_header; 183 memset(&webrtc_rtp_header, 0, sizeof(webrtc_rtp_header)); 184 webrtc_rtp_header.header = rtp_header; 185 CheckCSRC(webrtc_rtp_header); 186 187 size_t payload_data_length = payload_length - rtp_header.paddingLength; 188 189 bool is_first_packet_in_frame = false; 190 { 191 CriticalSectionScoped lock(critical_section_rtp_receiver_.get()); 192 if (HaveReceivedFrame()) { 193 is_first_packet_in_frame = 194 last_received_sequence_number_ + 1 == rtp_header.sequenceNumber && 195 last_received_timestamp_ != rtp_header.timestamp; 196 } else { 197 is_first_packet_in_frame = true; 198 } 199 } 200 201 int32_t ret_val = rtp_media_receiver_->ParseRtpPacket( 202 &webrtc_rtp_header, payload_specific, is_red, payload, payload_length, 203 clock_->TimeInMilliseconds(), is_first_packet_in_frame); 204 205 if (ret_val < 0) { 206 return false; 207 } 208 209 { 210 CriticalSectionScoped lock(critical_section_rtp_receiver_.get()); 211 212 last_receive_time_ = clock_->TimeInMilliseconds(); 213 last_received_payload_length_ = payload_data_length; 214 215 if (in_order) { 216 if (last_received_timestamp_ != rtp_header.timestamp) { 217 last_received_timestamp_ = rtp_header.timestamp; 218 last_received_frame_time_ms_ = clock_->TimeInMilliseconds(); 219 } 220 last_received_sequence_number_ = rtp_header.sequenceNumber; 221 } 222 } 223 return true; 224 } 225 226 TelephoneEventHandler* RtpReceiverImpl::GetTelephoneEventHandler() { 227 return rtp_media_receiver_->GetTelephoneEventHandler(); 228 } 229 230 bool RtpReceiverImpl::Timestamp(uint32_t* timestamp) const { 231 CriticalSectionScoped lock(critical_section_rtp_receiver_.get()); 232 if (!HaveReceivedFrame()) 233 return false; 234 *timestamp = last_received_timestamp_; 235 return true; 236 } 237 238 bool RtpReceiverImpl::LastReceivedTimeMs(int64_t* receive_time_ms) const { 239 CriticalSectionScoped lock(critical_section_rtp_receiver_.get()); 240 if (!HaveReceivedFrame()) 241 return false; 242 *receive_time_ms = last_received_frame_time_ms_; 243 return true; 244 } 245 246 bool RtpReceiverImpl::HaveReceivedFrame() const { 247 return last_received_frame_time_ms_ >= 0; 248 } 249 250 // Implementation note: must not hold critsect when called. 251 void RtpReceiverImpl::CheckSSRCChanged(const RTPHeader& rtp_header) { 252 bool new_ssrc = false; 253 bool re_initialize_decoder = false; 254 char payload_name[RTP_PAYLOAD_NAME_SIZE]; 255 size_t channels = 1; 256 uint32_t rate = 0; 257 258 { 259 CriticalSectionScoped lock(critical_section_rtp_receiver_.get()); 260 261 int8_t last_received_payload_type = 262 rtp_payload_registry_->last_received_payload_type(); 263 if (ssrc_ != rtp_header.ssrc || 264 (last_received_payload_type == -1 && ssrc_ == 0)) { 265 // We need the payload_type_ to make the call if the remote SSRC is 0. 266 new_ssrc = true; 267 268 last_received_timestamp_ = 0; 269 last_received_sequence_number_ = 0; 270 last_received_frame_time_ms_ = -1; 271 272 // Do we have a SSRC? Then the stream is restarted. 273 if (ssrc_ != 0) { 274 // Do we have the same codec? Then re-initialize coder. 275 if (rtp_header.payloadType == last_received_payload_type) { 276 re_initialize_decoder = true; 277 278 const Payload* payload = rtp_payload_registry_->PayloadTypeToPayload( 279 rtp_header.payloadType); 280 if (!payload) { 281 return; 282 } 283 payload_name[RTP_PAYLOAD_NAME_SIZE - 1] = 0; 284 strncpy(payload_name, payload->name, RTP_PAYLOAD_NAME_SIZE - 1); 285 if (payload->audio) { 286 channels = payload->typeSpecific.Audio.channels; 287 rate = payload->typeSpecific.Audio.rate; 288 } 289 } 290 } 291 ssrc_ = rtp_header.ssrc; 292 } 293 } 294 295 if (new_ssrc) { 296 // We need to get this to our RTCP sender and receiver. 297 // We need to do this outside critical section. 298 cb_rtp_feedback_->OnIncomingSSRCChanged(rtp_header.ssrc); 299 } 300 301 if (re_initialize_decoder) { 302 if (-1 == 303 cb_rtp_feedback_->OnInitializeDecoder( 304 rtp_header.payloadType, payload_name, 305 rtp_header.payload_type_frequency, channels, rate)) { 306 // New stream, same codec. 307 LOG(LS_ERROR) << "Failed to create decoder for payload type: " 308 << static_cast<int>(rtp_header.payloadType); 309 } 310 } 311 } 312 313 // Implementation note: must not hold critsect when called. 314 // TODO(phoglund): Move as much as possible of this code path into the media 315 // specific receivers. Basically this method goes through a lot of trouble to 316 // compute something which is only used by the media specific parts later. If 317 // this code path moves we can get rid of some of the rtp_receiver -> 318 // media_specific interface (such as CheckPayloadChange, possibly get/set 319 // last known payload). 320 int32_t RtpReceiverImpl::CheckPayloadChanged(const RTPHeader& rtp_header, 321 const int8_t first_payload_byte, 322 bool* is_red, 323 PayloadUnion* specific_payload) { 324 bool re_initialize_decoder = false; 325 326 char payload_name[RTP_PAYLOAD_NAME_SIZE]; 327 int8_t payload_type = rtp_header.payloadType; 328 329 { 330 CriticalSectionScoped lock(critical_section_rtp_receiver_.get()); 331 332 int8_t last_received_payload_type = 333 rtp_payload_registry_->last_received_payload_type(); 334 // TODO(holmer): Remove this code when RED parsing has been broken out from 335 // RtpReceiverAudio. 336 if (payload_type != last_received_payload_type) { 337 if (rtp_payload_registry_->red_payload_type() == payload_type) { 338 // Get the real codec payload type. 339 payload_type = first_payload_byte & 0x7f; 340 *is_red = true; 341 342 if (rtp_payload_registry_->red_payload_type() == payload_type) { 343 // Invalid payload type, traced by caller. If we proceeded here, 344 // this would be set as |_last_received_payload_type|, and we would no 345 // longer catch corrupt packets at this level. 346 return -1; 347 } 348 349 // When we receive RED we need to check the real payload type. 350 if (payload_type == last_received_payload_type) { 351 rtp_media_receiver_->GetLastMediaSpecificPayload(specific_payload); 352 return 0; 353 } 354 } 355 bool should_discard_changes = false; 356 357 rtp_media_receiver_->CheckPayloadChanged( 358 payload_type, specific_payload, 359 &should_discard_changes); 360 361 if (should_discard_changes) { 362 *is_red = false; 363 return 0; 364 } 365 366 const Payload* payload = 367 rtp_payload_registry_->PayloadTypeToPayload(payload_type); 368 if (!payload) { 369 // Not a registered payload type. 370 return -1; 371 } 372 payload_name[RTP_PAYLOAD_NAME_SIZE - 1] = 0; 373 strncpy(payload_name, payload->name, RTP_PAYLOAD_NAME_SIZE - 1); 374 375 rtp_payload_registry_->set_last_received_payload_type(payload_type); 376 377 re_initialize_decoder = true; 378 379 rtp_media_receiver_->SetLastMediaSpecificPayload(payload->typeSpecific); 380 rtp_media_receiver_->GetLastMediaSpecificPayload(specific_payload); 381 382 if (!payload->audio) { 383 bool media_type_unchanged = 384 rtp_payload_registry_->ReportMediaPayloadType(payload_type); 385 if (media_type_unchanged) { 386 // Only reset the decoder if the media codec type has changed. 387 re_initialize_decoder = false; 388 } 389 } 390 } else { 391 rtp_media_receiver_->GetLastMediaSpecificPayload(specific_payload); 392 *is_red = false; 393 } 394 } // End critsect. 395 396 if (re_initialize_decoder) { 397 if (-1 == 398 rtp_media_receiver_->InvokeOnInitializeDecoder( 399 cb_rtp_feedback_, payload_type, payload_name, *specific_payload)) { 400 return -1; // Wrong payload type. 401 } 402 } 403 return 0; 404 } 405 406 // Implementation note: must not hold critsect when called. 407 void RtpReceiverImpl::CheckCSRC(const WebRtcRTPHeader& rtp_header) { 408 int32_t num_csrcs_diff = 0; 409 uint32_t old_remote_csrc[kRtpCsrcSize]; 410 uint8_t old_num_csrcs = 0; 411 412 { 413 CriticalSectionScoped lock(critical_section_rtp_receiver_.get()); 414 415 if (!rtp_media_receiver_->ShouldReportCsrcChanges( 416 rtp_header.header.payloadType)) { 417 return; 418 } 419 old_num_csrcs = num_csrcs_; 420 if (old_num_csrcs > 0) { 421 // Make a copy of old. 422 memcpy(old_remote_csrc, current_remote_csrc_, 423 num_csrcs_ * sizeof(uint32_t)); 424 } 425 const uint8_t num_csrcs = rtp_header.header.numCSRCs; 426 if ((num_csrcs > 0) && (num_csrcs <= kRtpCsrcSize)) { 427 // Copy new. 428 memcpy(current_remote_csrc_, 429 rtp_header.header.arrOfCSRCs, 430 num_csrcs * sizeof(uint32_t)); 431 } 432 if (num_csrcs > 0 || old_num_csrcs > 0) { 433 num_csrcs_diff = num_csrcs - old_num_csrcs; 434 num_csrcs_ = num_csrcs; // Update stored CSRCs. 435 } else { 436 // No change. 437 return; 438 } 439 } // End critsect. 440 441 bool have_called_callback = false; 442 // Search for new CSRC in old array. 443 for (uint8_t i = 0; i < rtp_header.header.numCSRCs; ++i) { 444 const uint32_t csrc = rtp_header.header.arrOfCSRCs[i]; 445 446 bool found_match = false; 447 for (uint8_t j = 0; j < old_num_csrcs; ++j) { 448 if (csrc == old_remote_csrc[j]) { // old list 449 found_match = true; 450 break; 451 } 452 } 453 if (!found_match && csrc) { 454 // Didn't find it, report it as new. 455 have_called_callback = true; 456 cb_rtp_feedback_->OnIncomingCSRCChanged(csrc, true); 457 } 458 } 459 // Search for old CSRC in new array. 460 for (uint8_t i = 0; i < old_num_csrcs; ++i) { 461 const uint32_t csrc = old_remote_csrc[i]; 462 463 bool found_match = false; 464 for (uint8_t j = 0; j < rtp_header.header.numCSRCs; ++j) { 465 if (csrc == rtp_header.header.arrOfCSRCs[j]) { 466 found_match = true; 467 break; 468 } 469 } 470 if (!found_match && csrc) { 471 // Did not find it, report as removed. 472 have_called_callback = true; 473 cb_rtp_feedback_->OnIncomingCSRCChanged(csrc, false); 474 } 475 } 476 if (!have_called_callback) { 477 // If the CSRC list contain non-unique entries we will end up here. 478 // Using CSRC 0 to signal this event, not interop safe, other 479 // implementations might have CSRC 0 as a valid value. 480 if (num_csrcs_diff > 0) { 481 cb_rtp_feedback_->OnIncomingCSRCChanged(0, true); 482 } else if (num_csrcs_diff < 0) { 483 cb_rtp_feedback_->OnIncomingCSRCChanged(0, false); 484 } 485 } 486 } 487 488 } // namespace webrtc 489