LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/video - rtp_stream_receiver.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 389 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 40 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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/rtp_stream_receiver.h"
      12             : 
      13             : #include <vector>
      14             : #include <utility>
      15             : 
      16             : #include "webrtc/base/checks.h"
      17             : #include "webrtc/base/logging.h"
      18             : #include "webrtc/common_types.h"
      19             : #include "webrtc/config.h"
      20             : #include "webrtc/media/base/mediaconstants.h"
      21             : #include "webrtc/modules/pacing/packet_router.h"
      22             : #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
      23             : #include "webrtc/modules/rtp_rtcp/include/receive_statistics.h"
      24             : #include "webrtc/modules/rtp_rtcp/include/rtp_cvo.h"
      25             : #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
      26             : #include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h"
      27             : #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
      28             : #include "webrtc/modules/rtp_rtcp/include/ulpfec_receiver.h"
      29             : #include "webrtc/modules/video_coding/frame_object.h"
      30             : #include "webrtc/modules/video_coding/h264_sprop_parameter_sets.h"
      31             : #include "webrtc/modules/video_coding/h264_sps_pps_tracker.h"
      32             : #include "webrtc/modules/video_coding/packet_buffer.h"
      33             : #include "webrtc/modules/video_coding/video_coding_impl.h"
      34             : #include "webrtc/system_wrappers/include/field_trial.h"
      35             : #include "webrtc/system_wrappers/include/metrics.h"
      36             : #include "webrtc/system_wrappers/include/timestamp_extrapolator.h"
      37             : #include "webrtc/system_wrappers/include/trace.h"
      38             : #include "webrtc/video/receive_statistics_proxy.h"
      39             : #include "webrtc/video/vie_remb.h"
      40             : 
      41             : namespace webrtc {
      42             : 
      43             : namespace {
      44             : constexpr int kPacketBufferStartSize = 32;
      45             : constexpr int kPacketBufferMaxSixe = 2048;
      46             : }
      47             : 
      48           0 : std::unique_ptr<RtpRtcp> CreateRtpRtcpModule(
      49             :     ReceiveStatistics* receive_statistics,
      50             :     Transport* outgoing_transport,
      51             :     RtcpRttStats* rtt_stats,
      52             :     RtcpPacketTypeCounterObserver* rtcp_packet_type_counter_observer,
      53             :     RemoteBitrateEstimator* remote_bitrate_estimator,
      54             :     RtpPacketSender* paced_sender,
      55             :     TransportSequenceNumberAllocator* transport_sequence_number_allocator,
      56             :     RateLimiter* retransmission_rate_limiter) {
      57           0 :   RtpRtcp::Configuration configuration;
      58           0 :   configuration.audio = false;
      59           0 :   configuration.receiver_only = true;
      60           0 :   configuration.receive_statistics = receive_statistics;
      61           0 :   configuration.outgoing_transport = outgoing_transport;
      62           0 :   configuration.intra_frame_callback = nullptr;
      63           0 :   configuration.rtt_stats = rtt_stats;
      64           0 :   configuration.rtcp_packet_type_counter_observer =
      65             :       rtcp_packet_type_counter_observer;
      66           0 :   configuration.paced_sender = paced_sender;
      67           0 :   configuration.transport_sequence_number_allocator =
      68             :       transport_sequence_number_allocator;
      69           0 :   configuration.send_bitrate_observer = nullptr;
      70           0 :   configuration.send_frame_count_observer = nullptr;
      71           0 :   configuration.send_side_delay_observer = nullptr;
      72           0 :   configuration.send_packet_observer = nullptr;
      73           0 :   configuration.bandwidth_callback = nullptr;
      74           0 :   configuration.transport_feedback_callback = nullptr;
      75           0 :   configuration.retransmission_rate_limiter = retransmission_rate_limiter;
      76             : 
      77           0 :   std::unique_ptr<RtpRtcp> rtp_rtcp(RtpRtcp::CreateRtpRtcp(configuration));
      78           0 :   rtp_rtcp->SetSendingStatus(false);
      79           0 :   rtp_rtcp->SetSendingMediaStatus(false);
      80           0 :   rtp_rtcp->SetRTCPStatus(RtcpMode::kCompound);
      81             : 
      82           0 :   return rtp_rtcp;
      83             : }
      84             : 
      85             : static const int kPacketLogIntervalMs = 10000;
      86             : 
      87           0 : RtpStreamReceiver::RtpStreamReceiver(
      88             :     vcm::VideoReceiver* video_receiver,
      89             :     RemoteBitrateEstimator* remote_bitrate_estimator,
      90             :     Transport* transport,
      91             :     RtcpRttStats* rtt_stats,
      92             :     PacedSender* paced_sender,
      93             :     PacketRouter* packet_router,
      94             :     VieRemb* remb,
      95             :     const VideoReceiveStream::Config* config,
      96             :     ReceiveStatisticsProxy* receive_stats_proxy,
      97             :     ProcessThread* process_thread,
      98             :     RateLimiter* retransmission_rate_limiter,
      99             :     NackSender* nack_sender,
     100             :     KeyFrameRequestSender* keyframe_request_sender,
     101             :     video_coding::OnCompleteFrameCallback* complete_frame_callback,
     102           0 :     VCMTiming* timing)
     103           0 :     : clock_(Clock::GetRealTimeClock()),
     104             :       config_(*config),
     105             :       video_receiver_(video_receiver),
     106             :       remote_bitrate_estimator_(remote_bitrate_estimator),
     107             :       packet_router_(packet_router),
     108             :       remb_(remb),
     109             :       process_thread_(process_thread),
     110           0 :       ntp_estimator_(clock_),
     111             :       rtp_header_parser_(RtpHeaderParser::Create()),
     112           0 :       rtp_receiver_(RtpReceiver::CreateVideoReceiver(clock_,
     113             :                                                      this,
     114             :                                                      this,
     115             :                                                      &rtp_payload_registry_)),
     116           0 :       rtp_receive_statistics_(ReceiveStatistics::Create(clock_)),
     117             :       ulpfec_receiver_(UlpfecReceiver::Create(this)),
     118             :       receiving_(false),
     119             :       restored_packet_in_use_(false),
     120             :                         receiving_rid_enabled_(false),
     121             :       last_packet_log_ms_(-1),
     122             :       rtp_rtcp_(CreateRtpRtcpModule(rtp_receive_statistics_.get(),
     123             :                                     transport,
     124             :                                     rtt_stats,
     125             :                                     receive_stats_proxy,
     126           0 :                                     remote_bitrate_estimator_,
     127             :                                     paced_sender,
     128             :                                     packet_router,
     129             :                                     retransmission_rate_limiter)),
     130             :       complete_frame_callback_(complete_frame_callback),
     131             :       keyframe_request_sender_(keyframe_request_sender),
     132           0 :       timing_(timing) {
     133           0 :   packet_router_->AddRtpModule(rtp_rtcp_.get());
     134           0 :   rtp_receive_statistics_->RegisterRtpStatisticsCallback(receive_stats_proxy);
     135           0 :   rtp_receive_statistics_->RegisterRtcpStatisticsCallback(receive_stats_proxy);
     136             : 
     137           0 :   RTC_DCHECK(config_.rtp.rtcp_mode != RtcpMode::kOff)
     138             :       << "A stream should not be configured with RTCP disabled. This value is "
     139           0 :          "reserved for internal usage.";
     140           0 :   RTC_DCHECK(config_.rtp.remote_ssrc != 0);
     141             :   // TODO(pbos): What's an appropriate local_ssrc for receive-only streams?
     142           0 :   RTC_DCHECK(config_.rtp.local_ssrc != 0);
     143           0 :   RTC_DCHECK(config_.rtp.remote_ssrc != config_.rtp.local_ssrc);
     144             : 
     145           0 :   rtp_rtcp_->SetRTCPStatus(config_.rtp.rtcp_mode);
     146           0 :   rtp_rtcp_->SetSSRC(config_.rtp.local_ssrc);
     147           0 :   rtp_rtcp_->SetKeyFrameRequestMethod(kKeyFrameReqPliRtcp);
     148           0 :   if (config_.rtp.remb) {
     149           0 :     rtp_rtcp_->SetREMBStatus(true);
     150           0 :     remb_->AddReceiveChannel(rtp_rtcp_.get());
     151             :   }
     152             : 
     153           0 :   for (size_t i = 0; i < config_.rtp.extensions.size(); ++i) {
     154           0 :     EnableReceiveRtpHeaderExtension(config_.rtp.extensions[i].uri,
     155           0 :                                     config_.rtp.extensions[i].id);
     156             :   }
     157             : 
     158             :   static const int kMaxPacketAgeToNack = 450;
     159           0 :   const int max_reordering_threshold = (config_.rtp.nack.rtp_history_ms > 0)
     160           0 :                                            ? kMaxPacketAgeToNack
     161           0 :                                            : kDefaultMaxReorderingThreshold;
     162           0 :   rtp_receive_statistics_->SetMaxReorderingThreshold(max_reordering_threshold);
     163             : 
     164             :   // TODO(pbos): Support multiple RTX, per video payload.
     165           0 :   for (const auto& kv : config_.rtp.rtx) {
     166           0 :     RTC_DCHECK(kv.second.ssrc != 0);
     167           0 :     RTC_DCHECK(kv.second.payload_type != 0);
     168             : 
     169           0 :     rtp_payload_registry_.SetRtxSsrc(kv.second.ssrc);
     170           0 :     rtp_payload_registry_.SetRtxPayloadType(kv.second.payload_type,
     171           0 :                                             kv.first);
     172             :   }
     173             : 
     174           0 :   if (IsUlpfecEnabled()) {
     175           0 :     VideoCodec ulpfec_codec = {};
     176           0 :     ulpfec_codec.codecType = kVideoCodecULPFEC;
     177           0 :     strncpy(ulpfec_codec.plName, "ulpfec", sizeof(ulpfec_codec.plName));
     178           0 :     ulpfec_codec.plType = config_.rtp.ulpfec.ulpfec_payload_type;
     179           0 :     RTC_CHECK(AddReceiveCodec(ulpfec_codec));
     180             :   }
     181             : 
     182           0 :   if (IsRedEnabled()) {
     183           0 :     VideoCodec red_codec = {};
     184           0 :     red_codec.codecType = kVideoCodecRED;
     185           0 :     strncpy(red_codec.plName, "red", sizeof(red_codec.plName));
     186           0 :     red_codec.plType = config_.rtp.ulpfec.red_payload_type;
     187           0 :     RTC_CHECK(AddReceiveCodec(red_codec));
     188           0 :     if (config_.rtp.ulpfec.red_rtx_payload_type != -1) {
     189           0 :       rtp_payload_registry_.SetRtxPayloadType(
     190           0 :           config_.rtp.ulpfec.red_rtx_payload_type,
     191           0 :           config_.rtp.ulpfec.red_payload_type);
     192             :     }
     193             :   }
     194             : 
     195           0 :   rtp_rtcp_->SetTMMBRStatus(config_.rtp.tmmbr);
     196             : 
     197           0 :   rtp_rtcp_->SetKeyFrameRequestMethod(config_.rtp.keyframe_method);
     198             : 
     199           0 :   if (config_.rtp.rtcp_xr.receiver_reference_time_report)
     200           0 :     rtp_rtcp_->SetRtcpXrRrtrStatus(true);
     201             : 
     202             :   // Stats callback for CNAME changes.
     203           0 :   rtp_rtcp_->RegisterRtcpStatisticsCallback(receive_stats_proxy);
     204             : 
     205           0 :   process_thread_->RegisterModule(rtp_rtcp_.get());
     206             : 
     207           0 :   jitter_buffer_experiment_ =
     208           0 :       field_trial::FindFullName("WebRTC-NewVideoJitterBuffer") == "Enabled";
     209             : 
     210           0 :   if (jitter_buffer_experiment_) {
     211           0 :     nack_module_.reset(
     212           0 :         new NackModule(clock_, nack_sender, keyframe_request_sender));
     213           0 :     process_thread_->RegisterModule(nack_module_.get());
     214             : 
     215           0 :     packet_buffer_ = video_coding::PacketBuffer::Create(
     216           0 :         clock_, kPacketBufferStartSize, kPacketBufferMaxSixe, this);
     217           0 :     reference_finder_.reset(new video_coding::RtpFrameReferenceFinder(this));
     218             :   }
     219           0 : }
     220             : 
     221           0 : RtpStreamReceiver::~RtpStreamReceiver() {
     222           0 :   process_thread_->DeRegisterModule(rtp_rtcp_.get());
     223             : 
     224           0 :   if (jitter_buffer_experiment_)
     225           0 :     process_thread_->DeRegisterModule(nack_module_.get());
     226             : 
     227           0 :   packet_router_->RemoveRtpModule(rtp_rtcp_.get());
     228           0 :   rtp_rtcp_->SetREMBStatus(false);
     229           0 :   remb_->RemoveReceiveChannel(rtp_rtcp_.get());
     230           0 :   UpdateHistograms();
     231           0 : }
     232             : 
     233           0 : bool RtpStreamReceiver::AddReceiveCodec(
     234             :     const VideoCodec& video_codec,
     235             :     const std::map<std::string, std::string>& codec_params) {
     236           0 :   pt_codec_params_.insert(make_pair(video_codec.plType, codec_params));
     237           0 :   return AddReceiveCodec(video_codec);
     238             : }
     239             : 
     240           0 : bool RtpStreamReceiver::AddReceiveCodec(const VideoCodec& video_codec) {
     241           0 :   int8_t old_pltype = -1;
     242           0 :   if (rtp_payload_registry_.ReceivePayloadType(video_codec, &old_pltype) !=
     243             :       -1) {
     244           0 :     rtp_payload_registry_.DeRegisterReceivePayload(old_pltype);
     245             :   }
     246           0 :   return rtp_payload_registry_.RegisterReceivePayload(video_codec) == 0;
     247             : }
     248             : 
     249           0 : uint32_t RtpStreamReceiver::GetRemoteSsrc() const {
     250           0 :   return rtp_receiver_->SSRC();
     251             : }
     252             : 
     253           0 : int RtpStreamReceiver::GetCsrcs(uint32_t* csrcs) const {
     254           0 :   return rtp_receiver_->CSRCs(csrcs);
     255             : }
     256             : 
     257           0 : void RtpStreamReceiver::GetRID(char rid[256]) const {
     258           0 :   rtp_receiver_->GetRID(rid);
     259           0 : }
     260             : 
     261           0 : RtpReceiver* RtpStreamReceiver::GetRtpReceiver() const {
     262           0 :   return rtp_receiver_.get();
     263             : }
     264             : 
     265           0 : bool RtpStreamReceiver::SetReceiveRIDStatus(bool enable, int id) {
     266           0 :   rtc::CritScope lock(&receive_cs_);
     267           0 :   if (enable) {
     268           0 :     if (rtp_header_parser_->RegisterRtpHeaderExtension(
     269           0 :             kRtpExtensionRtpStreamId, id)) {
     270           0 :       receiving_rid_enabled_ = true;
     271           0 :       return true;
     272             :     } else {
     273           0 :       return false;
     274             :     }
     275             :   }
     276           0 :   receiving_rid_enabled_ = false;
     277           0 :   return rtp_header_parser_->DeregisterRtpHeaderExtension(
     278           0 :     kRtpExtensionRtpStreamId);
     279             : }
     280             : 
     281           0 : int32_t RtpStreamReceiver::OnReceivedPayloadData(
     282             :     const uint8_t* payload_data,
     283             :     size_t payload_size,
     284             :     const WebRtcRTPHeader* rtp_header) {
     285           0 :   RTC_DCHECK(video_receiver_);
     286           0 :   WebRtcRTPHeader rtp_header_with_ntp = *rtp_header;
     287           0 :   rtp_header_with_ntp.ntp_time_ms =
     288           0 :       ntp_estimator_.Estimate(rtp_header->header.timestamp);
     289           0 :   if (jitter_buffer_experiment_) {
     290           0 :     VCMPacket packet(payload_data, payload_size, rtp_header_with_ntp);
     291           0 :     timing_->IncomingTimestamp(packet.timestamp, clock_->TimeInMilliseconds());
     292           0 :     packet.timesNacked = nack_module_->OnReceivedPacket(packet);
     293             : 
     294           0 :     if (packet.codec == kVideoCodecH264) {
     295             :       // Only when we start to receive packets will we know what payload type
     296             :       // that will be used. When we know the payload type insert the correct
     297             :       // sps/pps into the tracker.
     298           0 :       if (packet.payloadType != last_payload_type_) {
     299           0 :         last_payload_type_ = packet.payloadType;
     300           0 :         InsertSpsPpsIntoTracker(packet.payloadType);
     301             :       }
     302             : 
     303           0 :       switch (tracker_.CopyAndFixBitstream(&packet)) {
     304             :         case video_coding::H264SpsPpsTracker::kRequestKeyframe:
     305           0 :           keyframe_request_sender_->RequestKeyFrame();
     306             :           FALLTHROUGH();
     307             :         case video_coding::H264SpsPpsTracker::kDrop:
     308           0 :           return 0;
     309             :         case video_coding::H264SpsPpsTracker::kInsert:
     310           0 :           break;
     311             :       }
     312             :     } else {
     313           0 :       uint8_t* data = new uint8_t[packet.sizeBytes];
     314           0 :       memcpy(data, packet.dataPtr, packet.sizeBytes);
     315           0 :       packet.dataPtr = data;
     316             :     }
     317             : 
     318           0 :     packet_buffer_->InsertPacket(&packet);
     319             :   } else {
     320           0 :     if (video_receiver_->IncomingPacket(payload_data, payload_size,
     321             :                                         rtp_header_with_ntp) != 0) {
     322             :       // Check this...
     323           0 :       return -1;
     324             :     }
     325             :   }
     326           0 :   return 0;
     327             : }
     328             : 
     329           0 : bool RtpStreamReceiver::OnRecoveredPacket(const uint8_t* rtp_packet,
     330             :                                           size_t rtp_packet_length) {
     331           0 :   RTPHeader header;
     332           0 :   if (!rtp_header_parser_->Parse(rtp_packet, rtp_packet_length, &header)) {
     333           0 :     return false;
     334             :   }
     335           0 :   header.payload_type_frequency = kVideoPayloadTypeFrequency;
     336           0 :   bool in_order = IsPacketInOrder(header);
     337           0 :   return ReceivePacket(rtp_packet, rtp_packet_length, header, in_order);
     338             : }
     339             : 
     340             : // TODO(pbos): Remove as soon as audio can handle a changing payload type
     341             : // without this callback.
     342           0 : int32_t RtpStreamReceiver::OnInitializeDecoder(
     343             :     const int8_t payload_type,
     344             :     const char payload_name[RTP_PAYLOAD_NAME_SIZE],
     345             :     const int frequency,
     346             :     const size_t channels,
     347             :     const uint32_t rate) {
     348           0 :   RTC_NOTREACHED();
     349           0 :   return 0;
     350             : }
     351             : 
     352           0 : void RtpStreamReceiver::OnIncomingSSRCChanged(const uint32_t ssrc) {
     353           0 :   rtp_rtcp_->SetRemoteSSRC(ssrc);
     354           0 : }
     355             : 
     356           0 : bool RtpStreamReceiver::DeliverRtp(const uint8_t* rtp_packet,
     357             :                                    size_t rtp_packet_length,
     358             :                                    const PacketTime& packet_time) {
     359           0 :   RTC_DCHECK(remote_bitrate_estimator_);
     360             :   {
     361           0 :     rtc::CritScope lock(&receive_cs_);
     362           0 :     if (!receiving_) {
     363           0 :       return false;
     364             :     }
     365             :   }
     366             : 
     367           0 :   RTPHeader header;
     368           0 :   if (!rtp_header_parser_->Parse(rtp_packet, rtp_packet_length,
     369           0 :                                  &header)) {
     370           0 :     return false;
     371             :   }
     372           0 :   size_t payload_length = rtp_packet_length - header.headerLength;
     373             :   int64_t arrival_time_ms;
     374           0 :   int64_t now_ms = clock_->TimeInMilliseconds();
     375           0 :   if (packet_time.timestamp != -1)
     376           0 :     arrival_time_ms = (packet_time.timestamp + 500) / 1000;
     377             :   else
     378           0 :     arrival_time_ms = now_ms;
     379             : 
     380             :   {
     381             :     // Periodically log the RTP header of incoming packets.
     382           0 :     rtc::CritScope lock(&receive_cs_);
     383           0 :     if (now_ms - last_packet_log_ms_ > kPacketLogIntervalMs) {
     384           0 :       std::stringstream ss;
     385           0 :       ss << "Packet received on SSRC: " << header.ssrc << " with payload type: "
     386           0 :          << static_cast<int>(header.payloadType) << ", timestamp: "
     387           0 :          << header.timestamp << ", sequence number: " << header.sequenceNumber
     388           0 :          << ", arrival time: " << arrival_time_ms;
     389           0 :       if (header.extension.hasTransmissionTimeOffset)
     390           0 :         ss << ", toffset: " << header.extension.transmissionTimeOffset;
     391           0 :       if (header.extension.hasAbsoluteSendTime)
     392           0 :         ss << ", abs send time: " << header.extension.absoluteSendTime;
     393           0 :                         if (header.extension.hasRID)
     394           0 :                                 ss << ", rid: " << header.extension.rid.get();
     395           0 :       LOG(LS_INFO) << ss.str();
     396           0 :       last_packet_log_ms_ = now_ms;
     397             :     }
     398             :   }
     399             : 
     400           0 :   remote_bitrate_estimator_->IncomingPacket(arrival_time_ms, payload_length,
     401           0 :                                             header);
     402           0 :   header.payload_type_frequency = kVideoPayloadTypeFrequency;
     403             : 
     404           0 :   bool in_order = IsPacketInOrder(header);
     405           0 :   rtp_payload_registry_.SetIncomingPayloadType(header);
     406           0 :   bool ret = ReceivePacket(rtp_packet, rtp_packet_length, header, in_order);
     407             :   // Update receive statistics after ReceivePacket.
     408             :   // Receive statistics will be reset if the payload type changes (make sure
     409             :   // that the first packet is included in the stats).
     410           0 :   rtp_receive_statistics_->IncomingPacket(
     411           0 :       header, rtp_packet_length, IsPacketRetransmitted(header, in_order));
     412           0 :   return ret;
     413             : }
     414             : 
     415           0 : int32_t RtpStreamReceiver::RequestKeyFrame() {
     416           0 :   return rtp_rtcp_->RequestKeyFrame();
     417             : }
     418             : 
     419           0 : int32_t RtpStreamReceiver::SliceLossIndicationRequest(
     420             :     const uint64_t picture_id) {
     421           0 :   return rtp_rtcp_->SendRTCPSliceLossIndication(
     422           0 :       static_cast<uint8_t>(picture_id));
     423             : }
     424             : 
     425           0 : bool RtpStreamReceiver::IsUlpfecEnabled() const {
     426           0 :   return config_.rtp.ulpfec.ulpfec_payload_type != -1;
     427             : }
     428             : 
     429           0 : bool RtpStreamReceiver::IsRedEnabled() const {
     430           0 :   return config_.rtp.ulpfec.red_payload_type != -1;
     431             : }
     432             : 
     433           0 : bool RtpStreamReceiver::IsRetransmissionsEnabled() const {
     434           0 :   return config_.rtp.nack.rtp_history_ms > 0;
     435             : }
     436             : 
     437           0 : void RtpStreamReceiver::RequestPacketRetransmit(
     438             :     const std::vector<uint16_t>& sequence_numbers) {
     439           0 :   rtp_rtcp_->SendNack(sequence_numbers);
     440           0 : }
     441             : 
     442           0 : int32_t RtpStreamReceiver::ResendPackets(const uint16_t* sequence_numbers,
     443             :                                          uint16_t length) {
     444           0 :   return rtp_rtcp_->SendNACK(sequence_numbers, length);
     445             : }
     446             : 
     447           0 : void RtpStreamReceiver::OnReceivedFrame(
     448             :     std::unique_ptr<video_coding::RtpFrameObject> frame) {
     449           0 :   reference_finder_->ManageFrame(std::move(frame));
     450           0 : }
     451             : 
     452           0 : void RtpStreamReceiver::OnCompleteFrame(
     453             :     std::unique_ptr<video_coding::FrameObject> frame) {
     454             :   {
     455           0 :     rtc::CritScope lock(&last_seq_num_cs_);
     456             :     video_coding::RtpFrameObject* rtp_frame =
     457           0 :         static_cast<video_coding::RtpFrameObject*>(frame.get());
     458           0 :     last_seq_num_for_pic_id_[rtp_frame->picture_id] = rtp_frame->last_seq_num();
     459             :   }
     460           0 :   complete_frame_callback_->OnCompleteFrame(std::move(frame));
     461           0 : }
     462             : 
     463           0 : void RtpStreamReceiver::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
     464           0 :   if (jitter_buffer_experiment_)
     465           0 :     nack_module_->UpdateRtt(max_rtt_ms);
     466           0 : }
     467             : 
     468           0 : bool RtpStreamReceiver::ReceivePacket(const uint8_t* packet,
     469             :                                       size_t packet_length,
     470             :                                       const RTPHeader& header,
     471             :                                       bool in_order) {
     472           0 :   if (rtp_payload_registry_.IsEncapsulated(header)) {
     473           0 :     return ParseAndHandleEncapsulatingHeader(packet, packet_length, header);
     474             :   }
     475           0 :   const uint8_t* payload = packet + header.headerLength;
     476           0 :   assert(packet_length >= header.headerLength);
     477           0 :   size_t payload_length = packet_length - header.headerLength;
     478             :   PayloadUnion payload_specific;
     479           0 :   if (!rtp_payload_registry_.GetPayloadSpecifics(header.payloadType,
     480             :                                                  &payload_specific)) {
     481           0 :     return false;
     482             :   }
     483           0 :   return rtp_receiver_->IncomingRtpPacket(header, payload, payload_length,
     484           0 :                                           payload_specific, in_order);
     485             : }
     486             : 
     487           0 : bool RtpStreamReceiver::ParseAndHandleEncapsulatingHeader(
     488             :     const uint8_t* packet, size_t packet_length, const RTPHeader& header) {
     489           0 :   if (rtp_payload_registry_.IsRed(header)) {
     490           0 :     int8_t ulpfec_pt = rtp_payload_registry_.ulpfec_payload_type();
     491           0 :     if (packet[header.headerLength] == ulpfec_pt) {
     492           0 :       rtp_receive_statistics_->FecPacketReceived(header, packet_length);
     493             :       // Notify video_receiver about received FEC packets to avoid NACKing these
     494             :       // packets.
     495           0 :       NotifyReceiverOfFecPacket(header);
     496             :     }
     497           0 :     if (ulpfec_receiver_->AddReceivedRedPacket(header, packet, packet_length,
     498           0 :                                                ulpfec_pt) != 0) {
     499           0 :       return false;
     500             :     }
     501           0 :     return ulpfec_receiver_->ProcessReceivedFec() == 0;
     502           0 :   } else if (rtp_payload_registry_.IsRtx(header)) {
     503           0 :     if (header.headerLength + header.paddingLength == packet_length) {
     504             :       // This is an empty packet and should be silently dropped before trying to
     505             :       // parse the RTX header.
     506           0 :       return true;
     507             :     }
     508             :     // Remove the RTX header and parse the original RTP header.
     509           0 :     if (packet_length < header.headerLength)
     510           0 :       return false;
     511           0 :     if (packet_length > sizeof(restored_packet_))
     512           0 :       return false;
     513           0 :     rtc::CritScope lock(&receive_cs_);
     514           0 :     if (restored_packet_in_use_) {
     515           0 :       LOG(LS_WARNING) << "Multiple RTX headers detected, dropping packet.";
     516           0 :       return false;
     517             :     }
     518           0 :     if (!rtp_payload_registry_.RestoreOriginalPacket(
     519           0 :             restored_packet_, packet, &packet_length, rtp_receiver_->SSRC(),
     520             :             header)) {
     521           0 :       LOG(LS_WARNING) << "Incoming RTX packet: Invalid RTP header ssrc: "
     522           0 :                       << header.ssrc << " payload type: "
     523           0 :                       << static_cast<int>(header.payloadType);
     524           0 :       return false;
     525             :     }
     526           0 :     restored_packet_in_use_ = true;
     527           0 :     bool ret = OnRecoveredPacket(restored_packet_, packet_length);
     528           0 :     restored_packet_in_use_ = false;
     529           0 :     return ret;
     530             :   }
     531           0 :   return false;
     532             : }
     533             : 
     534           0 : void RtpStreamReceiver::NotifyReceiverOfFecPacket(const RTPHeader& header) {
     535             :   int8_t last_media_payload_type =
     536           0 :       rtp_payload_registry_.last_received_media_payload_type();
     537           0 :   if (last_media_payload_type < 0) {
     538           0 :     LOG(LS_WARNING) << "Failed to get last media payload type.";
     539           0 :     return;
     540             :   }
     541             :   // Fake an empty media packet.
     542           0 :   WebRtcRTPHeader rtp_header = {};
     543           0 :   rtp_header.header = header;
     544           0 :   rtp_header.header.payloadType = last_media_payload_type;
     545           0 :   rtp_header.header.paddingLength = 0;
     546             :   PayloadUnion payload_specific;
     547           0 :   if (!rtp_payload_registry_.GetPayloadSpecifics(last_media_payload_type,
     548             :                                                  &payload_specific)) {
     549           0 :     LOG(LS_WARNING) << "Failed to get payload specifics.";
     550           0 :     return;
     551             :   }
     552           0 :   rtp_header.type.Video.codec = payload_specific.Video.videoCodecType;
     553           0 :   rtp_header.type.Video.rotation = kVideoRotation_0;
     554           0 :   if (header.extension.hasVideoRotation) {
     555           0 :     rtp_header.type.Video.rotation = header.extension.videoRotation;
     556             :   }
     557           0 :   rtp_header.type.Video.playout_delay = header.extension.playout_delay;
     558             : 
     559           0 :   OnReceivedPayloadData(nullptr, 0, &rtp_header);
     560             : }
     561             : 
     562           0 : bool RtpStreamReceiver::DeliverRtcp(const uint8_t* rtcp_packet,
     563             :                                     size_t rtcp_packet_length) {
     564             :   {
     565           0 :     rtc::CritScope lock(&receive_cs_);
     566           0 :     if (!receiving_) {
     567           0 :       return false;
     568             :     }
     569             :   }
     570             : 
     571           0 :   rtp_rtcp_->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length);
     572             : 
     573           0 :   int64_t rtt = 0;
     574           0 :   rtp_rtcp_->RTT(rtp_receiver_->SSRC(), &rtt, nullptr, nullptr, nullptr);
     575           0 :   if (rtt == 0) {
     576             :     // Waiting for valid rtt.
     577           0 :     return true;
     578             :   }
     579           0 :   uint32_t ntp_secs = 0;
     580           0 :   uint32_t ntp_frac = 0;
     581           0 :   uint32_t rtp_timestamp = 0;
     582           0 :   if (rtp_rtcp_->RemoteNTP(&ntp_secs, &ntp_frac, nullptr, nullptr,
     583           0 :                            &rtp_timestamp) != 0) {
     584             :     // Waiting for RTCP.
     585           0 :     return true;
     586             :   }
     587           0 :   ntp_estimator_.UpdateRtcpTimestamp(rtt, ntp_secs, ntp_frac, rtp_timestamp);
     588             : 
     589           0 :   return true;
     590             : }
     591             : 
     592           0 : void RtpStreamReceiver::FrameContinuous(uint16_t picture_id) {
     593           0 :   if (jitter_buffer_experiment_) {
     594           0 :     int seq_num = -1;
     595             :     {
     596           0 :       rtc::CritScope lock(&last_seq_num_cs_);
     597           0 :       auto seq_num_it = last_seq_num_for_pic_id_.find(picture_id);
     598           0 :       if (seq_num_it != last_seq_num_for_pic_id_.end())
     599           0 :         seq_num = seq_num_it->second;
     600             :     }
     601           0 :     if (seq_num != -1)
     602           0 :       nack_module_->ClearUpTo(seq_num);
     603             :   }
     604           0 : }
     605             : 
     606           0 : void RtpStreamReceiver::FrameDecoded(uint16_t picture_id) {
     607           0 :   if (jitter_buffer_experiment_) {
     608           0 :     int seq_num = -1;
     609             :     {
     610           0 :       rtc::CritScope lock(&last_seq_num_cs_);
     611           0 :       auto seq_num_it = last_seq_num_for_pic_id_.find(picture_id);
     612           0 :       if (seq_num_it != last_seq_num_for_pic_id_.end()) {
     613           0 :         seq_num = seq_num_it->second;
     614           0 :         last_seq_num_for_pic_id_.erase(last_seq_num_for_pic_id_.begin(),
     615           0 :                                        ++seq_num_it);
     616             :       }
     617             :     }
     618           0 :     if (seq_num != -1) {
     619           0 :       packet_buffer_->ClearTo(seq_num);
     620           0 :       reference_finder_->ClearTo(seq_num);
     621             :     }
     622             :   }
     623           0 : }
     624             : 
     625           0 : void RtpStreamReceiver::SignalNetworkState(NetworkState state) {
     626           0 :   rtp_rtcp_->SetRTCPStatus(state == kNetworkUp ? config_.rtp.rtcp_mode
     627           0 :                                                : RtcpMode::kOff);
     628           0 : }
     629             : 
     630           0 : void RtpStreamReceiver::StartReceive() {
     631           0 :   rtc::CritScope lock(&receive_cs_);
     632           0 :   receiving_ = true;
     633           0 : }
     634             : 
     635           0 : void RtpStreamReceiver::StopReceive() {
     636           0 :   rtc::CritScope lock(&receive_cs_);
     637           0 :   receiving_ = false;
     638           0 : }
     639             : 
     640           0 : bool RtpStreamReceiver::IsPacketInOrder(const RTPHeader& header) const {
     641             :   StreamStatistician* statistician =
     642           0 :       rtp_receive_statistics_->GetStatistician(header.ssrc);
     643           0 :   if (!statistician)
     644           0 :     return false;
     645           0 :   return statistician->IsPacketInOrder(header.sequenceNumber);
     646             : }
     647             : 
     648           0 : bool RtpStreamReceiver::IsPacketRetransmitted(const RTPHeader& header,
     649             :                                               bool in_order) const {
     650             :   // Retransmissions are handled separately if RTX is enabled.
     651           0 :   if (rtp_payload_registry_.RtxEnabled())
     652           0 :     return false;
     653             :   StreamStatistician* statistician =
     654           0 :       rtp_receive_statistics_->GetStatistician(header.ssrc);
     655           0 :   if (!statistician)
     656           0 :     return false;
     657             :   // Check if this is a retransmission.
     658           0 :   int64_t min_rtt = 0;
     659           0 :   rtp_rtcp_->RTT(rtp_receiver_->SSRC(), nullptr, nullptr, &min_rtt, nullptr);
     660           0 :   return !in_order &&
     661           0 :       statistician->IsRetransmitOfOldPacket(header, min_rtt);
     662             : }
     663             : 
     664           0 : void RtpStreamReceiver::UpdateHistograms() {
     665           0 :   FecPacketCounter counter = ulpfec_receiver_->GetPacketCounter();
     666           0 :   if (counter.first_packet_time_ms == -1)
     667           0 :     return;
     668             : 
     669             :   int64_t elapsed_sec =
     670           0 :       (clock_->TimeInMilliseconds() - counter.first_packet_time_ms) / 1000;
     671           0 :   if (elapsed_sec < metrics::kMinRunTimeInSeconds)
     672           0 :     return;
     673             : 
     674           0 :   if (counter.num_packets > 0) {
     675           0 :     RTC_HISTOGRAM_PERCENTAGE(
     676             :         "WebRTC.Video.ReceivedFecPacketsInPercent",
     677             :         static_cast<int>(counter.num_fec_packets * 100 / counter.num_packets));
     678             :   }
     679           0 :   if (counter.num_fec_packets > 0) {
     680           0 :     RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.RecoveredMediaPacketsInPercentOfFec",
     681             :                              static_cast<int>(counter.num_recovered_packets *
     682             :                                               100 / counter.num_fec_packets));
     683             :   }
     684             : }
     685             : 
     686           0 : void RtpStreamReceiver::EnableReceiveRtpHeaderExtension(
     687             :     const std::string& extension, int id) {
     688             :   // One-byte-extension local identifiers are in the range 1-14 inclusive.
     689           0 :   RTC_DCHECK_GE(id, 1);
     690           0 :   RTC_DCHECK_LE(id, 14);
     691           0 :   RTC_DCHECK(RtpExtension::IsSupportedForVideo(extension));
     692           0 :   RTC_CHECK(rtp_header_parser_->RegisterRtpHeaderExtension(
     693           0 :       StringToRtpExtensionType(extension), id));
     694           0 : }
     695             : 
     696           0 : void RtpStreamReceiver::InsertSpsPpsIntoTracker(uint8_t payload_type) {
     697           0 :   auto codec_params_it = pt_codec_params_.find(payload_type);
     698           0 :   if (codec_params_it == pt_codec_params_.end())
     699           0 :     return;
     700             : 
     701           0 :   LOG(LS_INFO) << "Found out of band supplied codec parameters for"
     702           0 :                << " payload type: " << payload_type;
     703             : 
     704           0 :   H264SpropParameterSets sprop_decoder;
     705             :   auto sprop_base64_it =
     706           0 :       codec_params_it->second.find("sprop-parameter-sets");
     707             : 
     708           0 :   if (sprop_base64_it == codec_params_it->second.end())
     709           0 :     return;
     710             : 
     711           0 :   if (!sprop_decoder.DecodeSprop(sprop_base64_it->second))
     712           0 :     return;
     713             : 
     714           0 :   tracker_.InsertSpsPps(sprop_decoder.sps_nalu(), sprop_decoder.pps_nalu());
     715             : }
     716             : 
     717             : }  // namespace webrtc

Generated by: LCOV version 1.13