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   return ReceivePacket(rtp_packet, rtp_packet_length, header, false);
    197 }
    198 
    199 void ViEReceiver::ReceivedBWEPacket(
    200     int64_t arrival_time_ms, int payload_size, const RTPHeader& header) {
    201   // Only forward if the incoming packet *and* the channel are both configured
    202   // to receive absolute sender time. RTP time stamps may have different rates
    203   // for audio and video and shouldn't be mixed.
    204   if (header.extension.hasAbsoluteSendTime && receiving_ast_enabled_) {
    205     remote_bitrate_estimator_->IncomingPacket(arrival_time_ms, payload_size,
    206                                               header);
    207   }
    208 }
    209 
    210 int ViEReceiver::InsertRTPPacket(const uint8_t* rtp_packet,
    211                                  int rtp_packet_length,
    212                                  const PacketTime& packet_time) {
    213   {
    214     CriticalSectionScoped cs(receive_cs_.get());
    215     if (!receiving_) {
    216       return -1;
    217     }
    218     if (rtp_dump_) {
    219       rtp_dump_->DumpPacket(rtp_packet,
    220                             static_cast<uint16_t>(rtp_packet_length));
    221     }
    222   }
    223 
    224   RTPHeader header;
    225   if (!rtp_header_parser_->Parse(rtp_packet, rtp_packet_length,
    226                                  &header)) {
    227     return -1;
    228   }
    229   int payload_length = rtp_packet_length - header.headerLength;
    230   int64_t arrival_time_ms;
    231   if (packet_time.timestamp != -1)
    232     arrival_time_ms = (packet_time.timestamp + 500) / 1000;
    233   else
    234     arrival_time_ms = TickTime::MillisecondTimestamp();
    235 
    236   remote_bitrate_estimator_->IncomingPacket(arrival_time_ms,
    237                                             payload_length, header);
    238   header.payload_type_frequency = kVideoPayloadTypeFrequency;
    239 
    240   bool in_order = IsPacketInOrder(header);
    241   rtp_payload_registry_->SetIncomingPayloadType(header);
    242   int ret = ReceivePacket(rtp_packet, rtp_packet_length, header, in_order)
    243       ? 0
    244       : -1;
    245   // Update receive statistics after ReceivePacket.
    246   // Receive statistics will be reset if the payload type changes (make sure
    247   // that the first packet is included in the stats).
    248   rtp_receive_statistics_->IncomingPacket(
    249       header, rtp_packet_length, IsPacketRetransmitted(header, in_order));
    250   return ret;
    251 }
    252 
    253 bool ViEReceiver::ReceivePacket(const uint8_t* packet,
    254                                 int packet_length,
    255                                 const RTPHeader& header,
    256                                 bool in_order) {
    257   if (rtp_payload_registry_->IsEncapsulated(header)) {
    258     return ParseAndHandleEncapsulatingHeader(packet, packet_length, header);
    259   }
    260   const uint8_t* payload = packet + header.headerLength;
    261   int payload_length = packet_length - header.headerLength;
    262   assert(payload_length >= 0);
    263   PayloadUnion payload_specific;
    264   if (!rtp_payload_registry_->GetPayloadSpecifics(header.payloadType,
    265                                                   &payload_specific)) {
    266     return false;
    267   }
    268   return rtp_receiver_->IncomingRtpPacket(header, payload, payload_length,
    269                                           payload_specific, in_order);
    270 }
    271 
    272 bool ViEReceiver::ParseAndHandleEncapsulatingHeader(const uint8_t* packet,
    273                                                     int packet_length,
    274                                                     const RTPHeader& header) {
    275   if (rtp_payload_registry_->IsRed(header)) {
    276     int8_t ulpfec_pt = rtp_payload_registry_->ulpfec_payload_type();
    277     if (packet[header.headerLength] == ulpfec_pt)
    278       rtp_receive_statistics_->FecPacketReceived(header.ssrc);
    279     if (fec_receiver_->AddReceivedRedPacket(
    280             header, packet, packet_length, ulpfec_pt) != 0) {
    281       return false;
    282     }
    283     return fec_receiver_->ProcessReceivedFec() == 0;
    284   } else if (rtp_payload_registry_->IsRtx(header)) {
    285     if (header.headerLength + header.paddingLength == packet_length) {
    286       // This is an empty packet and should be silently dropped before trying to
    287       // parse the RTX header.
    288       return true;
    289     }
    290     // Remove the RTX header and parse the original RTP header.
    291     if (packet_length < header.headerLength)
    292       return false;
    293     if (packet_length > static_cast<int>(sizeof(restored_packet_)))
    294       return false;
    295     CriticalSectionScoped cs(receive_cs_.get());
    296     if (restored_packet_in_use_) {
    297       LOG(LS_WARNING) << "Multiple RTX headers detected, dropping packet.";
    298       return false;
    299     }
    300     uint8_t* restored_packet_ptr = restored_packet_;
    301     if (!rtp_payload_registry_->RestoreOriginalPacket(
    302         &restored_packet_ptr, packet, &packet_length, rtp_receiver_->SSRC(),
    303         header)) {
    304       LOG(LS_WARNING) << "Incoming RTX packet: Invalid RTP header";
    305       return false;
    306     }
    307     restored_packet_in_use_ = true;
    308     bool ret = OnRecoveredPacket(restored_packet_ptr, packet_length);
    309     restored_packet_in_use_ = false;
    310     return ret;
    311   }
    312   return false;
    313 }
    314 
    315 int ViEReceiver::InsertRTCPPacket(const uint8_t* rtcp_packet,
    316                                   int rtcp_packet_length) {
    317   {
    318     CriticalSectionScoped cs(receive_cs_.get());
    319     if (!receiving_) {
    320       return -1;
    321     }
    322 
    323     if (rtp_dump_) {
    324       rtp_dump_->DumpPacket(
    325           rtcp_packet, static_cast<uint16_t>(rtcp_packet_length));
    326     }
    327 
    328     std::list<RtpRtcp*>::iterator it = rtp_rtcp_simulcast_.begin();
    329     while (it != rtp_rtcp_simulcast_.end()) {
    330       RtpRtcp* rtp_rtcp = *it++;
    331       rtp_rtcp->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length);
    332     }
    333   }
    334   assert(rtp_rtcp_);  // Should be set by owner at construction time.
    335   int ret = rtp_rtcp_->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length);
    336   if (ret != 0) {
    337     return ret;
    338   }
    339 
    340   ntp_estimator_->UpdateRtcpTimestamp(rtp_receiver_->SSRC(), rtp_rtcp_);
    341 
    342   return 0;
    343 }
    344 
    345 void ViEReceiver::StartReceive() {
    346   CriticalSectionScoped cs(receive_cs_.get());
    347   receiving_ = true;
    348 }
    349 
    350 void ViEReceiver::StopReceive() {
    351   CriticalSectionScoped cs(receive_cs_.get());
    352   receiving_ = false;
    353 }
    354 
    355 int ViEReceiver::StartRTPDump(const char file_nameUTF8[1024]) {
    356   CriticalSectionScoped cs(receive_cs_.get());
    357   if (rtp_dump_) {
    358     // Restart it if it already exists and is started
    359     rtp_dump_->Stop();
    360   } else {
    361     rtp_dump_ = RtpDump::CreateRtpDump();
    362     if (rtp_dump_ == NULL) {
    363       return -1;
    364     }
    365   }
    366   if (rtp_dump_->Start(file_nameUTF8) != 0) {
    367     RtpDump::DestroyRtpDump(rtp_dump_);
    368     rtp_dump_ = NULL;
    369     return -1;
    370   }
    371   return 0;
    372 }
    373 
    374 int ViEReceiver::StopRTPDump() {
    375   CriticalSectionScoped cs(receive_cs_.get());
    376   if (rtp_dump_) {
    377     if (rtp_dump_->IsActive()) {
    378       rtp_dump_->Stop();
    379     }
    380     RtpDump::DestroyRtpDump(rtp_dump_);
    381     rtp_dump_ = NULL;
    382   } else {
    383     return -1;
    384   }
    385   return 0;
    386 }
    387 
    388 void ViEReceiver::GetReceiveBandwidthEstimatorStats(
    389     ReceiveBandwidthEstimatorStats* output) const {
    390   remote_bitrate_estimator_->GetStats(output);
    391 }
    392 
    393 ReceiveStatistics* ViEReceiver::GetReceiveStatistics() const {
    394   return rtp_receive_statistics_.get();
    395 }
    396 
    397 bool ViEReceiver::IsPacketInOrder(const RTPHeader& header) const {
    398   StreamStatistician* statistician =
    399       rtp_receive_statistics_->GetStatistician(header.ssrc);
    400   if (!statistician)
    401     return false;
    402   return statistician->IsPacketInOrder(header.sequenceNumber);
    403 }
    404 
    405 bool ViEReceiver::IsPacketRetransmitted(const RTPHeader& header,
    406                                         bool in_order) const {
    407   // Retransmissions are handled separately if RTX is enabled.
    408   if (rtp_payload_registry_->RtxEnabled())
    409     return false;
    410   StreamStatistician* statistician =
    411       rtp_receive_statistics_->GetStatistician(header.ssrc);
    412   if (!statistician)
    413     return false;
    414   // Check if this is a retransmission.
    415   uint16_t min_rtt = 0;
    416   rtp_rtcp_->RTT(rtp_receiver_->SSRC(), NULL, NULL, &min_rtt, NULL);
    417   return !in_order &&
    418       statistician->IsRetransmitOfOldPacket(header, min_rtt);
    419 }
    420 }  // namespace webrtc
    421