LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/rtp_rtcp/source - flexfec_receiver.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 59 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 5 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_receiver.h"
      12             : 
      13             : #include "webrtc/base/logging.h"
      14             : #include "webrtc/base/scoped_ref_ptr.h"
      15             : 
      16             : namespace webrtc {
      17             : 
      18             : namespace {
      19             : 
      20             : using Packet = ForwardErrorCorrection::Packet;
      21             : using ReceivedPacket = ForwardErrorCorrection::ReceivedPacket;
      22             : 
      23             : // Minimum header size (in bytes) of a well-formed non-singular FlexFEC packet.
      24             : constexpr size_t kMinFlexfecHeaderSize = 20;
      25             : 
      26             : // How often to log the recovered packets to the text log.
      27             : constexpr int kPacketLogIntervalMs = 10000;
      28             : 
      29             : }  // namespace
      30             : 
      31           0 : FlexfecReceiver::FlexfecReceiver(
      32             :     uint32_t ssrc,
      33             :     uint32_t protected_media_ssrc,
      34           0 :     RecoveredPacketReceiver* recovered_packet_receiver)
      35             :     : ssrc_(ssrc),
      36             :       protected_media_ssrc_(protected_media_ssrc),
      37             :       erasure_code_(ForwardErrorCorrection::CreateFlexfec()),
      38             :       recovered_packet_receiver_(recovered_packet_receiver),
      39           0 :       clock_(Clock::GetRealTimeClock()),
      40           0 :       last_recovered_packet_ms_(-1) {
      41             :   // It's OK to create this object on a different thread/task queue than
      42             :   // the one used during main operation.
      43           0 :   sequence_checker_.Detach();
      44           0 : }
      45             : 
      46             : FlexfecReceiver::~FlexfecReceiver() = default;
      47             : 
      48           0 : bool FlexfecReceiver::AddAndProcessReceivedPacket(
      49             :     const RtpPacketReceived& packet) {
      50           0 :   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
      51           0 :   if (!AddReceivedPacket(std::move(packet))) {
      52           0 :     return false;
      53             :   }
      54           0 :   return ProcessReceivedPackets();
      55             : }
      56             : 
      57           0 : FecPacketCounter FlexfecReceiver::GetPacketCounter() const {
      58           0 :   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
      59           0 :   return packet_counter_;
      60             : }
      61             : 
      62           0 : bool FlexfecReceiver::AddReceivedPacket(const RtpPacketReceived& packet) {
      63           0 :   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
      64             : 
      65             :   // RTP packets with a full base header (12 bytes), but without payload,
      66             :   // could conceivably be useful in the decoding. Therefore we check
      67             :   // with a non-strict inequality here.
      68           0 :   RTC_DCHECK_GE(packet.size(), kRtpHeaderSize);
      69             : 
      70             :   // Demultiplex based on SSRC, and insert into erasure code decoder.
      71           0 :   std::unique_ptr<ReceivedPacket> received_packet(new ReceivedPacket());
      72           0 :   received_packet->seq_num = packet.SequenceNumber();
      73           0 :   received_packet->ssrc = packet.Ssrc();
      74           0 :   if (received_packet->ssrc == ssrc_) {
      75             :     // This is a FlexFEC packet.
      76           0 :     if (packet.payload_size() < kMinFlexfecHeaderSize) {
      77           0 :       LOG(LS_WARNING) << "Truncated FlexFEC packet, discarding.";
      78           0 :       return false;
      79             :     }
      80           0 :     received_packet->is_fec = true;
      81           0 :     ++packet_counter_.num_fec_packets;
      82             : 
      83             :     // Insert packet payload into erasure code.
      84             :     // TODO(brandtr): Remove this memcpy when the FEC packet classes
      85             :     // are using COW buffers internally.
      86           0 :     received_packet->pkt = rtc::scoped_refptr<Packet>(new Packet());
      87           0 :     auto payload = packet.payload();
      88           0 :     memcpy(received_packet->pkt->data, payload.data(), payload.size());
      89           0 :     received_packet->pkt->length = payload.size();
      90             :   } else {
      91             :     // This is a media packet, or a FlexFEC packet belonging to some
      92             :     // other FlexFEC stream.
      93           0 :     if (received_packet->ssrc != protected_media_ssrc_) {
      94           0 :       return false;
      95             :     }
      96           0 :     received_packet->is_fec = false;
      97             : 
      98             :     // Insert entire packet into erasure code.
      99             :     // TODO(brandtr): Remove this memcpy too.
     100           0 :     received_packet->pkt = rtc::scoped_refptr<Packet>(new Packet());
     101           0 :     memcpy(received_packet->pkt->data, packet.data(), packet.size());
     102           0 :     received_packet->pkt->length = packet.size();
     103             :   }
     104             : 
     105           0 :   received_packets_.push_back(std::move(received_packet));
     106           0 :   ++packet_counter_.num_packets;
     107             : 
     108           0 :   return true;
     109             : }
     110             : 
     111             : // Note that the implementation of this member function and the implementation
     112             : // in UlpfecReceiver::ProcessReceivedFec() are slightly different.
     113             : // This implementation only returns _recovered_ media packets through the
     114             : // callback, whereas the implementation in UlpfecReceiver returns _all inserted_
     115             : // media packets through the callback. The latter behaviour makes sense
     116             : // for ULPFEC, since the ULPFEC receiver is owned by the RtpStreamReceiver.
     117             : // Here, however, the received media pipeline is more decoupled from the
     118             : // FlexFEC decoder, and we therefore do not interfere with the reception
     119             : // of non-recovered media packets.
     120           0 : bool FlexfecReceiver::ProcessReceivedPackets() {
     121           0 :   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
     122             : 
     123             :   // Decode.
     124           0 :   if (!received_packets_.empty()) {
     125           0 :     if (erasure_code_->DecodeFec(&received_packets_, &recovered_packets_) !=
     126             :         0) {
     127           0 :       return false;
     128             :     }
     129             :   }
     130             :   // Return recovered packets through callback.
     131           0 :   for (const auto& recovered_packet : recovered_packets_) {
     132           0 :     if (recovered_packet->returned) {
     133           0 :       continue;
     134             :     }
     135           0 :     ++packet_counter_.num_recovered_packets;
     136           0 :     if (!recovered_packet_receiver_->OnRecoveredPacket(
     137           0 :             recovered_packet->pkt->data, recovered_packet->pkt->length)) {
     138           0 :       return false;
     139             :     }
     140           0 :     recovered_packet->returned = true;
     141             :     // Periodically log the incoming packets.
     142           0 :     int64_t now_ms = clock_->TimeInMilliseconds();
     143           0 :     if (now_ms - last_recovered_packet_ms_ > kPacketLogIntervalMs) {
     144             :       uint32_t media_ssrc =
     145           0 :           ForwardErrorCorrection::ParseSsrc(recovered_packet->pkt->data);
     146           0 :       LOG(LS_VERBOSE) << "Recovered media packet with SSRC: " << media_ssrc
     147           0 :                       << " from FlexFEC stream with SSRC: " << ssrc_ << ".";
     148           0 :       last_recovered_packet_ms_ = now_ms;
     149             :     }
     150             :   }
     151           0 :   return true;
     152             : }
     153             : 
     154             : }  // namespace webrtc

Generated by: LCOV version 1.13