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 |
11 #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.h" | 11 #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.h" |
12 | 12 |
13 #include <assert.h> | 13 #include <assert.h> |
14 #include <math.h> | 14 #include <math.h> |
15 #include <stdlib.h> | 15 #include <stdlib.h> |
16 #include <string.h> | 16 #include <string.h> |
17 | 17 |
18 #include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h" | 18 #include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h" |
19 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h" | 19 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h" |
20 #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h" | 20 #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h" |
21 #include "webrtc/system_wrappers/interface/logging.h" | 21 #include "webrtc/system_wrappers/interface/logging.h" |
22 | 22 |
23 namespace webrtc { | 23 namespace webrtc { |
24 | 24 |
25 using RtpUtility::GetCurrentRTP; | 25 using RtpUtility::GetCurrentRTP; |
26 using RtpUtility::Payload; | 26 using RtpUtility::Payload; |
27 using RtpUtility::StringCompare; | 27 using RtpUtility::StringCompare; |
28 | 28 |
29 RtpReceiver* RtpReceiver::CreateVideoReceiver( | 29 RtpReceiver* RtpReceiver::CreateVideoReceiver( |
30 int id, Clock* clock, | 30 Clock* clock, |
31 RtpData* incoming_payload_callback, | 31 RtpData* incoming_payload_callback, |
32 RtpFeedback* incoming_messages_callback, | 32 RtpFeedback* incoming_messages_callback, |
33 RTPPayloadRegistry* rtp_payload_registry) { | 33 RTPPayloadRegistry* rtp_payload_registry) { |
34 if (!incoming_payload_callback) | 34 if (!incoming_payload_callback) |
35 incoming_payload_callback = NullObjectRtpData(); | 35 incoming_payload_callback = NullObjectRtpData(); |
36 if (!incoming_messages_callback) | 36 if (!incoming_messages_callback) |
37 incoming_messages_callback = NullObjectRtpFeedback(); | 37 incoming_messages_callback = NullObjectRtpFeedback(); |
38 return new RtpReceiverImpl( | 38 return new RtpReceiverImpl( |
39 id, clock, NullObjectRtpAudioFeedback(), incoming_messages_callback, | 39 clock, NullObjectRtpAudioFeedback(), incoming_messages_callback, |
40 rtp_payload_registry, | 40 rtp_payload_registry, |
41 RTPReceiverStrategy::CreateVideoStrategy(incoming_payload_callback)); | 41 RTPReceiverStrategy::CreateVideoStrategy(incoming_payload_callback)); |
42 } | 42 } |
43 | 43 |
44 RtpReceiver* RtpReceiver::CreateAudioReceiver( | 44 RtpReceiver* RtpReceiver::CreateAudioReceiver( |
45 int id, Clock* clock, | 45 Clock* clock, |
46 RtpAudioFeedback* incoming_audio_feedback, | 46 RtpAudioFeedback* incoming_audio_feedback, |
47 RtpData* incoming_payload_callback, | 47 RtpData* incoming_payload_callback, |
48 RtpFeedback* incoming_messages_callback, | 48 RtpFeedback* incoming_messages_callback, |
49 RTPPayloadRegistry* rtp_payload_registry) { | 49 RTPPayloadRegistry* rtp_payload_registry) { |
50 if (!incoming_audio_feedback) | 50 if (!incoming_audio_feedback) |
51 incoming_audio_feedback = NullObjectRtpAudioFeedback(); | 51 incoming_audio_feedback = NullObjectRtpAudioFeedback(); |
52 if (!incoming_payload_callback) | 52 if (!incoming_payload_callback) |
53 incoming_payload_callback = NullObjectRtpData(); | 53 incoming_payload_callback = NullObjectRtpData(); |
54 if (!incoming_messages_callback) | 54 if (!incoming_messages_callback) |
55 incoming_messages_callback = NullObjectRtpFeedback(); | 55 incoming_messages_callback = NullObjectRtpFeedback(); |
56 return new RtpReceiverImpl( | 56 return new RtpReceiverImpl( |
57 id, clock, incoming_audio_feedback, incoming_messages_callback, | 57 clock, incoming_audio_feedback, incoming_messages_callback, |
58 rtp_payload_registry, | 58 rtp_payload_registry, |
59 RTPReceiverStrategy::CreateAudioStrategy(id, incoming_payload_callback, | 59 RTPReceiverStrategy::CreateAudioStrategy(incoming_payload_callback, |
60 incoming_audio_feedback)); | 60 incoming_audio_feedback)); |
61 } | 61 } |
62 | 62 |
63 RtpReceiverImpl::RtpReceiverImpl(int32_t id, | 63 RtpReceiverImpl::RtpReceiverImpl( |
64 Clock* clock, | 64 Clock* clock, |
65 RtpAudioFeedback* incoming_audio_messages_callback, | 65 RtpAudioFeedback* incoming_audio_messages_callback, |
66 RtpFeedback* incoming_messages_callback, | 66 RtpFeedback* incoming_messages_callback, |
67 RTPPayloadRegistry* rtp_payload_registry, | 67 RTPPayloadRegistry* rtp_payload_registry, |
68 RTPReceiverStrategy* rtp_media_receiver) | 68 RTPReceiverStrategy* rtp_media_receiver) |
69 : clock_(clock), | 69 : clock_(clock), |
70 rtp_payload_registry_(rtp_payload_registry), | 70 rtp_payload_registry_(rtp_payload_registry), |
71 rtp_media_receiver_(rtp_media_receiver), | 71 rtp_media_receiver_(rtp_media_receiver), |
72 id_(id), | |
73 cb_rtp_feedback_(incoming_messages_callback), | 72 cb_rtp_feedback_(incoming_messages_callback), |
74 critical_section_rtp_receiver_( | 73 critical_section_rtp_receiver_( |
75 CriticalSectionWrapper::CreateCriticalSection()), | 74 CriticalSectionWrapper::CreateCriticalSection()), |
76 last_receive_time_(0), | 75 last_receive_time_(0), |
77 last_received_payload_length_(0), | 76 last_received_payload_length_(0), |
78 ssrc_(0), | 77 ssrc_(0), |
79 num_csrcs_(0), | 78 num_csrcs_(0), |
80 current_remote_csrc_(), | 79 current_remote_csrc_(), |
81 last_received_timestamp_(0), | 80 last_received_timestamp_(0), |
82 last_received_frame_time_ms_(-1), | 81 last_received_frame_time_ms_(-1), |
83 last_received_sequence_number_(0), | 82 last_received_sequence_number_(0), |
84 nack_method_(kNackOff) { | 83 nack_method_(kNackOff) { |
85 assert(incoming_audio_messages_callback); | 84 assert(incoming_audio_messages_callback); |
86 assert(incoming_messages_callback); | 85 assert(incoming_messages_callback); |
87 | 86 |
88 memset(current_remote_csrc_, 0, sizeof(current_remote_csrc_)); | 87 memset(current_remote_csrc_, 0, sizeof(current_remote_csrc_)); |
89 } | 88 } |
90 | 89 |
91 RtpReceiverImpl::~RtpReceiverImpl() { | 90 RtpReceiverImpl::~RtpReceiverImpl() { |
92 for (int i = 0; i < num_csrcs_; ++i) { | 91 for (int i = 0; i < num_csrcs_; ++i) { |
93 cb_rtp_feedback_->OnIncomingCSRCChanged(id_, current_remote_csrc_[i], | 92 cb_rtp_feedback_->OnIncomingCSRCChanged(current_remote_csrc_[i], false); |
94 false); | |
95 } | 93 } |
96 } | 94 } |
97 | 95 |
98 int32_t RtpReceiverImpl::RegisterReceivePayload( | 96 int32_t RtpReceiverImpl::RegisterReceivePayload( |
99 const char payload_name[RTP_PAYLOAD_NAME_SIZE], | 97 const char payload_name[RTP_PAYLOAD_NAME_SIZE], |
100 const int8_t payload_type, | 98 const int8_t payload_type, |
101 const uint32_t frequency, | 99 const uint32_t frequency, |
102 const uint8_t channels, | 100 const uint8_t channels, |
103 const uint32_t rate) { | 101 const uint32_t rate) { |
104 CriticalSectionScoped lock(critical_section_rtp_receiver_.get()); | 102 CriticalSectionScoped lock(critical_section_rtp_receiver_.get()); |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 } | 290 } |
293 } | 291 } |
294 } | 292 } |
295 ssrc_ = rtp_header.ssrc; | 293 ssrc_ = rtp_header.ssrc; |
296 } | 294 } |
297 } | 295 } |
298 | 296 |
299 if (new_ssrc) { | 297 if (new_ssrc) { |
300 // We need to get this to our RTCP sender and receiver. | 298 // We need to get this to our RTCP sender and receiver. |
301 // We need to do this outside critical section. | 299 // We need to do this outside critical section. |
302 cb_rtp_feedback_->OnIncomingSSRCChanged(id_, rtp_header.ssrc); | 300 cb_rtp_feedback_->OnIncomingSSRCChanged(rtp_header.ssrc); |
303 } | 301 } |
304 | 302 |
305 if (re_initialize_decoder) { | 303 if (re_initialize_decoder) { |
306 if (-1 == cb_rtp_feedback_->OnInitializeDecoder( | 304 if (-1 == |
307 id_, rtp_header.payloadType, payload_name, | 305 cb_rtp_feedback_->OnInitializeDecoder( |
308 rtp_header.payload_type_frequency, channels, rate)) { | 306 rtp_header.payloadType, payload_name, |
| 307 rtp_header.payload_type_frequency, channels, rate)) { |
309 // New stream, same codec. | 308 // New stream, same codec. |
310 LOG(LS_ERROR) << "Failed to create decoder for payload type: " | 309 LOG(LS_ERROR) << "Failed to create decoder for payload type: " |
311 << static_cast<int>(rtp_header.payloadType); | 310 << static_cast<int>(rtp_header.payloadType); |
312 } | 311 } |
313 } | 312 } |
314 } | 313 } |
315 | 314 |
316 // Implementation note: must not hold critsect when called. | 315 // Implementation note: must not hold critsect when called. |
317 // TODO(phoglund): Move as much as possible of this code path into the media | 316 // TODO(phoglund): Move as much as possible of this code path into the media |
318 // specific receivers. Basically this method goes through a lot of trouble to | 317 // specific receivers. Basically this method goes through a lot of trouble to |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 re_initialize_decoder = false; | 389 re_initialize_decoder = false; |
391 } | 390 } |
392 } | 391 } |
393 } else { | 392 } else { |
394 rtp_media_receiver_->GetLastMediaSpecificPayload(specific_payload); | 393 rtp_media_receiver_->GetLastMediaSpecificPayload(specific_payload); |
395 is_red = false; | 394 is_red = false; |
396 } | 395 } |
397 } // End critsect. | 396 } // End critsect. |
398 | 397 |
399 if (re_initialize_decoder) { | 398 if (re_initialize_decoder) { |
400 if (-1 == rtp_media_receiver_->InvokeOnInitializeDecoder( | 399 if (-1 == |
401 cb_rtp_feedback_, id_, payload_type, payload_name, | 400 rtp_media_receiver_->InvokeOnInitializeDecoder( |
402 *specific_payload)) { | 401 cb_rtp_feedback_, payload_type, payload_name, *specific_payload)) { |
403 return -1; // Wrong payload type. | 402 return -1; // Wrong payload type. |
404 } | 403 } |
405 } | 404 } |
406 return 0; | 405 return 0; |
407 } | 406 } |
408 | 407 |
409 // Implementation note: must not hold critsect when called. | 408 // Implementation note: must not hold critsect when called. |
410 void RtpReceiverImpl::CheckCSRC(const WebRtcRTPHeader& rtp_header) { | 409 void RtpReceiverImpl::CheckCSRC(const WebRtcRTPHeader& rtp_header) { |
411 int32_t num_csrcs_diff = 0; | 410 int32_t num_csrcs_diff = 0; |
412 uint32_t old_remote_csrc[kRtpCsrcSize]; | 411 uint32_t old_remote_csrc[kRtpCsrcSize]; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 bool found_match = false; | 448 bool found_match = false; |
450 for (uint8_t j = 0; j < old_num_csrcs; ++j) { | 449 for (uint8_t j = 0; j < old_num_csrcs; ++j) { |
451 if (csrc == old_remote_csrc[j]) { // old list | 450 if (csrc == old_remote_csrc[j]) { // old list |
452 found_match = true; | 451 found_match = true; |
453 break; | 452 break; |
454 } | 453 } |
455 } | 454 } |
456 if (!found_match && csrc) { | 455 if (!found_match && csrc) { |
457 // Didn't find it, report it as new. | 456 // Didn't find it, report it as new. |
458 have_called_callback = true; | 457 have_called_callback = true; |
459 cb_rtp_feedback_->OnIncomingCSRCChanged(id_, csrc, true); | 458 cb_rtp_feedback_->OnIncomingCSRCChanged(csrc, true); |
460 } | 459 } |
461 } | 460 } |
462 // Search for old CSRC in new array. | 461 // Search for old CSRC in new array. |
463 for (uint8_t i = 0; i < old_num_csrcs; ++i) { | 462 for (uint8_t i = 0; i < old_num_csrcs; ++i) { |
464 const uint32_t csrc = old_remote_csrc[i]; | 463 const uint32_t csrc = old_remote_csrc[i]; |
465 | 464 |
466 bool found_match = false; | 465 bool found_match = false; |
467 for (uint8_t j = 0; j < rtp_header.header.numCSRCs; ++j) { | 466 for (uint8_t j = 0; j < rtp_header.header.numCSRCs; ++j) { |
468 if (csrc == rtp_header.header.arrOfCSRCs[j]) { | 467 if (csrc == rtp_header.header.arrOfCSRCs[j]) { |
469 found_match = true; | 468 found_match = true; |
470 break; | 469 break; |
471 } | 470 } |
472 } | 471 } |
473 if (!found_match && csrc) { | 472 if (!found_match && csrc) { |
474 // Did not find it, report as removed. | 473 // Did not find it, report as removed. |
475 have_called_callback = true; | 474 have_called_callback = true; |
476 cb_rtp_feedback_->OnIncomingCSRCChanged(id_, csrc, false); | 475 cb_rtp_feedback_->OnIncomingCSRCChanged(csrc, false); |
477 } | 476 } |
478 } | 477 } |
479 if (!have_called_callback) { | 478 if (!have_called_callback) { |
480 // If the CSRC list contain non-unique entries we will end up here. | 479 // If the CSRC list contain non-unique entries we will end up here. |
481 // Using CSRC 0 to signal this event, not interop safe, other | 480 // Using CSRC 0 to signal this event, not interop safe, other |
482 // implementations might have CSRC 0 as a valid value. | 481 // implementations might have CSRC 0 as a valid value. |
483 if (num_csrcs_diff > 0) { | 482 if (num_csrcs_diff > 0) { |
484 cb_rtp_feedback_->OnIncomingCSRCChanged(id_, 0, true); | 483 cb_rtp_feedback_->OnIncomingCSRCChanged(0, true); |
485 } else if (num_csrcs_diff < 0) { | 484 } else if (num_csrcs_diff < 0) { |
486 cb_rtp_feedback_->OnIncomingCSRCChanged(id_, 0, false); | 485 cb_rtp_feedback_->OnIncomingCSRCChanged(0, false); |
487 } | 486 } |
488 } | 487 } |
489 } | 488 } |
490 | 489 |
491 } // namespace webrtc | 490 } // namespace webrtc |
OLD | NEW |