Home | History | Annotate | Download | only in source
      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