Home | History | Annotate | Download | only in video_engine
      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/video_engine/vie_receiver.h"
     12 
     13 #include <vector>
     14 
     15 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
     16 #include "webrtc/modules/rtp_rtcp/interface/fec_receiver.h"
     17 #include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
     18 #include "webrtc/modules/rtp_rtcp/interface/remote_ntp_time_estimator.h"
     19 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
     20 #include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
     21 #include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
     22 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
     23 #include "webrtc/modules/utility/interface/rtp_dump.h"
     24 #include "webrtc/modules/video_coding/main/interface/video_coding.h"
     25 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
     26 #include "webrtc/system_wrappers/interface/logging.h"
     27 #include "webrtc/system_wrappers/interface/tick_util.h"
     28 #include "webrtc/system_wrappers/interface/timestamp_extrapolator.h"
     29 #include "webrtc/system_wrappers/interface/trace.h"
     30 
     31 namespace webrtc {
     32 
     33 ViEReceiver::ViEReceiver(const int32_t channel_id,
     34                          VideoCodingModule* module_vcm,
     35                          RemoteBitrateEstimator* remote_bitrate_estimator,
     36                          RtpFeedback* rtp_feedback)
     37     : receive_cs_(CriticalSectionWrapper::CreateCriticalSection()),
     38       rtp_header_parser_(RtpHeaderParser::Create()),
     39       rtp_payload_registry_(new RTPPayloadRegistry(
     40           RTPPayloadStrategy::CreateStrategy(false))),
     41       rtp_receiver_(RtpReceiver::CreateVideoReceiver(
     42           channel_id, Clock::GetRealTimeClock(), this, rtp_feedback,
     43           rtp_payload_registry_.get())),
     44       rtp_receive_statistics_(ReceiveStatistics::Create(
     45           Clock::GetRealTimeClock())),
     46       fec_receiver_(FecReceiver::Create(this)),
     47       rtp_rtcp_(NULL),
     48       vcm_(module_vcm),
     49       remote_bitrate_estimator_(remote_bitrate_estimator),
     50       ntp_estimator_(new RemoteNtpTimeEstimator(Clock::GetRealTimeClock())),
     51       rtp_dump_(NULL),
     52       receiving_(false),
     53       restored_packet_in_use_(false),
     54       receiving_ast_enabled_(false) {
     55   assert(remote_bitrate_estimator);
     56 }
     57 
     58 ViEReceiver::~ViEReceiver() {
     59   if (rtp_dump_) {
     60     rtp_dump_->Stop();
     61     RtpDump::DestroyRtpDump(rtp_dump_);
     62     rtp_dump_ = NULL;
     63   }
     64 }
     65 
     66 bool ViEReceiver::SetReceiveCodec(const VideoCodec& video_codec) {
     67   int8_t old_pltype = -1;
     68   if (rtp_payload_registry_->ReceivePayloadType(video_codec.plName,
     69                                                 kVideoPayloadTypeFrequency,
     70                                                 0,
     71                                                 video_codec.maxBitrate,
     72                                                 &old_pltype) != -1) {
     73     rtp_payload_registry_->DeRegisterReceivePayload(old_pltype);
     74   }
     75 
     76   return RegisterPayload(video_codec);
     77 }
     78 
     79 bool ViEReceiver::RegisterPayload(const VideoCodec& video_codec) {
     80   return rtp_receiver_->RegisterReceivePayload(video_codec.plName,
     81                                                video_codec.plType,
     82                                                kVideoPayloadTypeFrequency,
     83                                                0,
     84                                                video_codec.maxBitrate) == 0;
     85 }
     86 
     87 void ViEReceiver::SetNackStatus(bool enable,
     88                                 int max_nack_reordering_threshold) {
     89   if (!enable) {
     90     // Reset the threshold back to the lower default threshold when NACK is
     91     // disabled since we no longer will be receiving retransmissions.
     92     max_nack_reordering_threshold = kDefaultMaxReorderingThreshold;
     93   }
     94   rtp_receive_statistics_->SetMaxReorderingThreshold(
     95       max_nack_reordering_threshold);
     96   rtp_receiver_->SetNACKStatus(enable ? kNackRtcp : kNackOff);
     97 }
     98 
     99 void ViEReceiver::SetRtxPayloadType(int payload_type) {
    100   rtp_payload_registry_->SetRtxPayloadType(payload_type);
    101 }
    102 
    103 void ViEReceiver::SetRtxSsrc(uint32_t ssrc) {
    104   rtp_payload_registry_->SetRtxSsrc(ssrc);
    105 }
    106 
    107 uint32_t ViEReceiver::GetRemoteSsrc() const {
    108   return rtp_receiver_->SSRC();
    109 }
    110 
    111 int ViEReceiver::GetCsrcs(uint32_t* csrcs) const {
    112   return rtp_receiver_->CSRCs(csrcs);
    113 }
    114 
    115 void ViEReceiver::SetRtpRtcpModule(RtpRtcp* module) {
    116   rtp_rtcp_ = module;
    117 }
    118 
    119 RtpReceiver* ViEReceiver::GetRtpReceiver() const {
    120   return rtp_receiver_.get();
    121 }
    122 
    123 void ViEReceiver::RegisterSimulcastRtpRtcpModules(
    124     const std::list<RtpRtcp*>& rtp_modules) {
    125   CriticalSectionScoped cs(receive_cs_.get());
    126   rtp_rtcp_simulcast_.clear();
    127 
    128   if (!rtp_modules.empty()) {
    129     rtp_rtcp_simulcast_.insert(rtp_rtcp_simulcast_.begin(),
    130                                rtp_modules.begin(),
    131                                rtp_modules.end());
    132   }
    133 }
    134 
    135 bool ViEReceiver::SetReceiveTimestampOffsetStatus(bool enable, int id) {
    136   if (enable) {
    137     return rtp_header_parser_->RegisterRtpHeaderExtension(
    138         kRtpExtensionTransmissionTimeOffset, id);
    139   } else {
    140     return rtp_header_parser_->DeregisterRtpHeaderExtension(
    141         kRtpExtensionTransmissionTimeOffset);
    142   }
    143 }
    144 
    145 bool ViEReceiver::SetReceiveAbsoluteSendTimeStatus(bool enable, int id) {
    146   if (enable) {
    147     if (rtp_header_parser_->RegisterRtpHeaderExtension(
    148         kRtpExtensionAbsoluteSendTime, id)) {
    149       receiving_ast_enabled_ = true;
    150       return true;
    151     } else {
    152       return false;
    153     }
    154   } else {
    155     receiving_ast_enabled_ = false;
    156     return rtp_header_parser_->DeregisterRtpHeaderExtension(
    157         kRtpExtensionAbsoluteSendTime);
    158   }
    159 }
    160 
    161 int ViEReceiver::ReceivedRTPPacket(const void* rtp_packet,
    162                                    int rtp_packet_length,
    163                                    const PacketTime& packet_time) {
    164   return InsertRTPPacket(static_cast<const uint8_t*>(rtp_packet),
    165                          rtp_packet_length, packet_time);
    166 }
    167 
    168 int ViEReceiver::ReceivedRTCPPacket(const void* rtcp_packet,
    169                                     int rtcp_packet_length) {
    170   return InsertRTCPPacket(static_cast<const uint8_t*>(rtcp_packet),
    171                           rtcp_packet_length);
    172 }
    173 
    174 int32_t ViEReceiver::OnReceivedPayloadData(
    175     const uint8_t* payload_data, const uint16_t payload_size,
    176     const WebRtcRTPHeader* rtp_header) {
    177   WebRtcRTPHeader rtp_header_with_ntp = *rtp_header;
    178   rtp_header_with_ntp.ntp_time_ms =
    179       ntp_estimator_->Estimate(rtp_header->header.timestamp);
    180   if (vcm_->IncomingPacket(payload_data,
    181                            payload_size,
    182                            rtp_header_with_ntp) != 0) {
    183     // Check this...
    184     return -1;
    185   }
    186   return 0;
    187 }
    188 
    189 bool ViEReceiver::OnRecoveredPacket(const uint8_t* rtp_packet,
    190                                     int rtp_packet_length) {
    191   RTPHeader header;
    192   if (!rtp_header_parser_->Parse(rtp_packet, rtp_packet_length, &header)) {
    193     return false;
    194   }
    195   header.payload_type_frequency = kVideoPayloadTypeFrequency;
    196   bool in_order = IsPacketInOrder(header);
    197   return ReceivePacket(rtp_packet, rtp_packet_length, header, in_order);
    198 }
    199 
    200 void ViEReceiver::ReceivedBWEPacket(
    201     int64_t arrival_time_ms, int payload_size, const RTPHeader& header) {
    202   // Only forward if the incoming packet *and* the channel are both configured
    203   // to receive absolute sender time. RTP time stamps may have different rates
    204   // for audio and video and shouldn't be mixed.
    205   if (header.extension.hasAbsoluteSendTime && receiving_ast_enabled_) {
    206     remote_bitrate_estimator_->IncomingPacket(arrival_time_ms, payload_size,
    207                                               header);
    208   }
    209 }
    210 
    211 int ViEReceiver::InsertRTPPacket(const uint8_t* rtp_packet,
    212                                  int rtp_packet_length,
    213                                  const PacketTime& packet_time) {
    214   {
    215     CriticalSectionScoped cs(receive_cs_.get());
    216     if (!receiving_) {
    217       return -1;
    218     }
    219     if (rtp_dump_) {
    220       rtp_dump_->DumpPacket(rtp_packet,
    221                             static_cast<uint16_t>(rtp_packet_length));
    222     }
    223   }
    224 
    225   RTPHeader header;
    226   if (!rtp_header_parser_->Parse(rtp_packet, rtp_packet_length,
    227                                  &header)) {
    228     return -1;
    229   }
    230   int payload_length = rtp_packet_length - header.headerLength;
    231   int64_t arrival_time_ms;
    232   if (packet_time.timestamp != -1)
    233     arrival_time_ms = (packet_time.timestamp + 500) / 1000;
    234   else
    235     arrival_time_ms = TickTime::MillisecondTimestamp();
    236 
    237   remote_bitrate_estimator_->IncomingPacket(arrival_time_ms,
    238                                             payload_length, header);
    239   header.payload_type_frequency = kVideoPayloadTypeFrequency;
    240 
    241   bool in_order = IsPacketInOrder(header);
    242   rtp_payload_registry_->SetIncomingPayloadType(header);
    243   int ret = ReceivePacket(rtp_packet, rtp_packet_length, header, in_order)
    244       ? 0
    245       : -1;
    246   // Update receive statistics after ReceivePacket.
    247   // Receive statistics will be reset if the payload type changes (make sure
    248   // that the first packet is included in the stats).
    249   rtp_receive_statistics_->IncomingPacket(
    250       header, rtp_packet_length, IsPacketRetransmitted(header, in_order));
    251   return ret;
    252 }
    253 
    254 bool ViEReceiver::ReceivePacket(const uint8_t* packet,
    255                                 int packet_length,
    256                                 const RTPHeader& header,
    257                                 bool in_order) {
    258   if (rtp_payload_registry_->IsEncapsulated(header)) {
    259     return ParseAndHandleEncapsulatingHeader(packet, packet_length, header);
    260   }
    261   const uint8_t* payload = packet + header.headerLength;
    262   int payload_length = packet_length - header.headerLength;
    263   assert(payload_length >= 0);
    264   PayloadUnion payload_specific;
    265   if (!rtp_payload_registry_->GetPayloadSpecifics(header.payloadType,
    266                                                   &payload_specific)) {
    267     return false;
    268   }
    269   return rtp_receiver_->IncomingRtpPacket(header, payload, payload_length,
    270                                           payload_specific, in_order);
    271 }
    272 
    273 bool ViEReceiver::ParseAndHandleEncapsulatingHeader(const uint8_t* packet,
    274                                                     int packet_length,
    275                                                     const RTPHeader& header) {
    276   if (rtp_payload_registry_->IsRed(header)) {
    277     int8_t ulpfec_pt = rtp_payload_registry_->ulpfec_payload_type();
    278     if (packet[header.headerLength] == ulpfec_pt)
    279       rtp_receive_statistics_->FecPacketReceived(header.ssrc);
    280     if (fec_receiver_->AddReceivedRedPacket(
    281             header, packet, packet_length, ulpfec_pt) != 0) {
    282       return false;
    283     }
    284     return fec_receiver_->ProcessReceivedFec() == 0;
    285   } else if (rtp_payload_registry_->IsRtx(header)) {
    286     if (header.headerLength + header.paddingLength == packet_length) {
    287       // This is an empty packet and should be silently dropped before trying to
    288       // parse the RTX header.
    289       return true;
    290     }
    291     // Remove the RTX header and parse the original RTP header.
    292     if (packet_length < header.headerLength)
    293       return false;
    294     if (packet_length > static_cast<int>(sizeof(restored_packet_)))
    295       return false;
    296     CriticalSectionScoped cs(receive_cs_.get());
    297     if (restored_packet_in_use_) {
    298       LOG(LS_WARNING) << "Multiple RTX headers detected, dropping packet.";
    299       return false;
    300     }
    301     uint8_t* restored_packet_ptr = restored_packet_;
    302     if (!rtp_payload_registry_->RestoreOriginalPacket(
    303         &restored_packet_ptr, packet, &packet_length, rtp_receiver_->SSRC(),
    304         header)) {
    305       LOG(LS_WARNING) << "Incoming RTX packet: Invalid RTP header";
    306       return false;
    307     }
    308     restored_packet_in_use_ = true;
    309     bool ret = OnRecoveredPacket(restored_packet_ptr, packet_length);
    310     restored_packet_in_use_ = false;
    311     return ret;
    312   }
    313   return false;
    314 }
    315 
    316 int ViEReceiver::InsertRTCPPacket(const uint8_t* rtcp_packet,
    317                                   int rtcp_packet_length) {
    318   {
    319     CriticalSectionScoped cs(receive_cs_.get());
    320     if (!receiving_) {
    321       return -1;
    322     }
    323 
    324     if (rtp_dump_) {
    325       rtp_dump_->DumpPacket(
    326           rtcp_packet, static_cast<uint16_t>(rtcp_packet_length));
    327     }
    328 
    329     std::list<RtpRtcp*>::iterator it = rtp_rtcp_simulcast_.begin();
    330     while (it != rtp_rtcp_simulcast_.end()) {
    331       RtpRtcp* rtp_rtcp = *it++;
    332       rtp_rtcp->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length);
    333     }
    334   }
    335   assert(rtp_rtcp_);  // Should be set by owner at construction time.
    336   int ret = rtp_rtcp_->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length);
    337   if (ret != 0) {
    338     return ret;
    339   }
    340 
    341   ntp_estimator_->UpdateRtcpTimestamp(rtp_receiver_->SSRC(), rtp_rtcp_);
    342 
    343   return 0;
    344 }
    345 
    346 void ViEReceiver::StartReceive() {
    347   CriticalSectionScoped cs(receive_cs_.get());
    348   receiving_ = true;
    349 }
    350 
    351 void ViEReceiver::StopReceive() {
    352   CriticalSectionScoped cs(receive_cs_.get());
    353   receiving_ = false;
    354 }
    355 
    356 int ViEReceiver::StartRTPDump(const char file_nameUTF8[1024]) {
    357   CriticalSectionScoped cs(receive_cs_.get());
    358   if (rtp_dump_) {
    359     // Restart it if it already exists and is started
    360     rtp_dump_->Stop();
    361   } else {
    362     rtp_dump_ = RtpDump::CreateRtpDump();
    363     if (rtp_dump_ == NULL) {
    364       return -1;
    365     }
    366   }
    367   if (rtp_dump_->Start(file_nameUTF8) != 0) {
    368     RtpDump::DestroyRtpDump(rtp_dump_);
    369     rtp_dump_ = NULL;
    370     return -1;
    371   }
    372   return 0;
    373 }
    374 
    375 int ViEReceiver::StopRTPDump() {
    376   CriticalSectionScoped cs(receive_cs_.get());
    377   if (rtp_dump_) {
    378     if (rtp_dump_->IsActive()) {
    379       rtp_dump_->Stop();
    380     }
    381     RtpDump::DestroyRtpDump(rtp_dump_);
    382     rtp_dump_ = NULL;
    383   } else {
    384     return -1;
    385   }
    386   return 0;
    387 }
    388 
    389 void ViEReceiver::GetReceiveBandwidthEstimatorStats(
    390     ReceiveBandwidthEstimatorStats* output) const {
    391   remote_bitrate_estimator_->GetStats(output);
    392 }
    393 
    394 ReceiveStatistics* ViEReceiver::GetReceiveStatistics() const {
    395   return rtp_receive_statistics_.get();
    396 }
    397 
    398 bool ViEReceiver::IsPacketInOrder(const RTPHeader& header) const {
    399   StreamStatistician* statistician =
    400       rtp_receive_statistics_->GetStatistician(header.ssrc);
    401   if (!statistician)
    402     return false;
    403   return statistician->IsPacketInOrder(header.sequenceNumber);
    404 }
    405 
    406 bool ViEReceiver::IsPacketRetransmitted(const RTPHeader& header,
    407                                         bool in_order) const {
    408   // Retransmissions are handled separately if RTX is enabled.
    409   if (rtp_payload_registry_->RtxEnabled())
    410     return false;
    411   StreamStatistician* statistician =
    412       rtp_receive_statistics_->GetStatistician(header.ssrc);
    413   if (!statistician)
    414     return false;
    415   // Check if this is a retransmission.
    416   uint16_t min_rtt = 0;
    417   rtp_rtcp_->RTT(rtp_receiver_->SSRC(), NULL, NULL, &min_rtt, NULL);
    418   return !in_order &&
    419       statistician->IsRetransmitOfOldPacket(header, min_rtt);
    420 }
    421 }  // namespace webrtc
    422