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

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2016 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/include/flexfec_sender.h"
      12             : 
      13             : #include <utility>
      14             : 
      15             : #include "webrtc/base/logging.h"
      16             : #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
      17             : #include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h"
      18             : #include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h"
      19             : 
      20             : namespace webrtc {
      21             : 
      22             : namespace {
      23             : 
      24             : // Let first sequence number be in the first half of the interval.
      25             : constexpr uint16_t kMaxInitRtpSeqNumber = 0x7fff;
      26             : 
      27             : // See breakdown in flexfec_header_reader_writer.cc.
      28             : constexpr size_t kFlexfecMaxHeaderSize = 32;
      29             : 
      30             : // Since we will mainly use FlexFEC to protect video streams, we use a 90 kHz
      31             : // clock for the RTP timestamps. (This is according to the RFC, which states
      32             : // that it is RECOMMENDED to use the same clock frequency for FlexFEC as for
      33             : // the protected media stream.)
      34             : // The constant converts from clock millisecond timestamps to the 90 kHz
      35             : // RTP timestamp.
      36             : const int kMsToRtpTimestamp = kVideoPayloadTypeFrequency / 1000;
      37             : 
      38             : // How often to log the generated FEC packets to the text log.
      39             : constexpr int64_t kPacketLogIntervalMs = 10000;
      40             : 
      41           0 : RtpHeaderExtensionMap RegisterBweExtensions(
      42             :     const std::vector<RtpExtension>& rtp_header_extensions) {
      43           0 :   RtpHeaderExtensionMap map;
      44           0 :   for (const auto& extension : rtp_header_extensions) {
      45           0 :     if (extension.uri == TransportSequenceNumber::kUri) {
      46           0 :       map.Register<TransportSequenceNumber>(extension.id);
      47           0 :     } else if (extension.uri == AbsoluteSendTime::kUri) {
      48           0 :       map.Register<AbsoluteSendTime>(extension.id);
      49           0 :     } else if (extension.uri == TransmissionOffset::kUri) {
      50           0 :       map.Register<TransmissionOffset>(extension.id);
      51             :     } else {
      52           0 :       LOG(LS_INFO) << "FlexfecSender only supports RTP header extensions for "
      53           0 :                    << "BWE, so the extension " << extension.ToString()
      54           0 :                    << " will not be used.";
      55             :     }
      56             :   }
      57           0 :   return map;
      58             : }
      59             : 
      60             : }  // namespace
      61             : 
      62           0 : FlexfecSender::FlexfecSender(
      63             :     int payload_type,
      64             :     uint32_t ssrc,
      65             :     uint32_t protected_media_ssrc,
      66             :     const std::vector<RtpExtension>& rtp_header_extensions,
      67           0 :     Clock* clock)
      68             :     : clock_(clock),
      69           0 :       random_(clock_->TimeInMicroseconds()),
      70             :       last_generated_packet_ms_(-1),
      71             :       payload_type_(payload_type),
      72             :       // Initialize the timestamp offset and RTP sequence numbers randomly.
      73             :       // (This is not intended to be cryptographically strong.)
      74           0 :       timestamp_offset_(random_.Rand<uint32_t>()),
      75             :       ssrc_(ssrc),
      76             :       protected_media_ssrc_(protected_media_ssrc),
      77           0 :       seq_num_(random_.Rand(1, kMaxInitRtpSeqNumber)),
      78           0 :       ulpfec_generator_(ForwardErrorCorrection::CreateFlexfec()),
      79           0 :       rtp_header_extension_map_(RegisterBweExtensions(rtp_header_extensions)) {
      80             :   // This object should not have been instantiated if FlexFEC is disabled.
      81           0 :   RTC_DCHECK_GE(payload_type, 0);
      82           0 :   RTC_DCHECK_LE(payload_type, 127);
      83           0 : }
      84             : 
      85             : FlexfecSender::~FlexfecSender() = default;
      86             : 
      87             : // We are reusing the implementation from UlpfecGenerator for SetFecParameters,
      88             : // AddRtpPacketAndGenerateFec, and FecAvailable.
      89           0 : void FlexfecSender::SetFecParameters(const FecProtectionParams& params) {
      90           0 :   ulpfec_generator_.SetFecParameters(params);
      91           0 : }
      92             : 
      93           0 : bool FlexfecSender::AddRtpPacketAndGenerateFec(const RtpPacketToSend& packet) {
      94             :   // TODO(brandtr): Generalize this SSRC check when we support multistream
      95             :   // protection.
      96           0 :   RTC_DCHECK_EQ(packet.Ssrc(), protected_media_ssrc_);
      97           0 :   return ulpfec_generator_.AddRtpPacketAndGenerateFec(
      98           0 :              packet.data(), packet.payload_size(), packet.headers_size()) == 0;
      99             : }
     100             : 
     101           0 : bool FlexfecSender::FecAvailable() const {
     102           0 :   return ulpfec_generator_.FecAvailable();
     103             : }
     104             : 
     105           0 : std::vector<std::unique_ptr<RtpPacketToSend>> FlexfecSender::GetFecPackets() {
     106           0 :   std::vector<std::unique_ptr<RtpPacketToSend>> fec_packets_to_send;
     107           0 :   fec_packets_to_send.reserve(ulpfec_generator_.generated_fec_packets_.size());
     108           0 :   for (const auto& fec_packet : ulpfec_generator_.generated_fec_packets_) {
     109             :     std::unique_ptr<RtpPacketToSend> fec_packet_to_send(
     110           0 :         new RtpPacketToSend(&rtp_header_extension_map_));
     111             : 
     112             :     // RTP header.
     113           0 :     fec_packet_to_send->SetMarker(false);
     114           0 :     fec_packet_to_send->SetPayloadType(payload_type_);
     115           0 :     fec_packet_to_send->SetSequenceNumber(seq_num_++);
     116           0 :     fec_packet_to_send->SetTimestamp(
     117           0 :         timestamp_offset_ +
     118             :         static_cast<uint32_t>(kMsToRtpTimestamp *
     119           0 :                               clock_->TimeInMilliseconds()));
     120             :     // Set "capture time" so that the TransmissionOffset header extension
     121             :     // can be set by the RTPSender.
     122           0 :     fec_packet_to_send->set_capture_time_ms(clock_->TimeInMilliseconds());
     123           0 :     fec_packet_to_send->SetSsrc(ssrc_);
     124             :     // Reserve extensions, if registered. These will be set by the RTPSender.
     125           0 :     fec_packet_to_send->ReserveExtension<AbsoluteSendTime>();
     126           0 :     fec_packet_to_send->ReserveExtension<TransmissionOffset>();
     127           0 :     fec_packet_to_send->ReserveExtension<TransportSequenceNumber>();
     128             : 
     129             :     // RTP payload.
     130           0 :     uint8_t* payload = fec_packet_to_send->AllocatePayload(fec_packet->length);
     131           0 :     memcpy(payload, fec_packet->data, fec_packet->length);
     132             : 
     133           0 :     fec_packets_to_send.push_back(std::move(fec_packet_to_send));
     134             :   }
     135           0 :   ulpfec_generator_.ResetState();
     136             : 
     137           0 :   int64_t now_ms = clock_->TimeInMilliseconds();
     138           0 :   if (!fec_packets_to_send.empty() &&
     139           0 :       now_ms - last_generated_packet_ms_ > kPacketLogIntervalMs) {
     140           0 :     LOG(LS_VERBOSE) << "Generated " << fec_packets_to_send.size()
     141           0 :                     << " FlexFEC packets with payload type: " << payload_type_
     142           0 :                     << " and SSRC: " << ssrc_ << ".";
     143           0 :     last_generated_packet_ms_ = now_ms;
     144             :   }
     145             : 
     146           0 :   return fec_packets_to_send;
     147             : }
     148             : 
     149             : // The overhead is BWE RTP header extensions and FlexFEC header.
     150           0 : size_t FlexfecSender::MaxPacketOverhead() const {
     151           0 :   return rtp_header_extension_map_.GetTotalLengthInBytes() +
     152           0 :          kFlexfecMaxHeaderSize;
     153             : }
     154             : 
     155             : }  // namespace webrtc

Generated by: LCOV version 1.13