LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtcp_packet - remb.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 67 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 3 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/source/rtcp_packet/remb.h"
      12             : 
      13             : #include <utility>
      14             : 
      15             : #include "webrtc/base/checks.h"
      16             : #include "webrtc/base/logging.h"
      17             : #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
      18             : #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/common_header.h"
      19             : 
      20             : namespace webrtc {
      21             : namespace rtcp {
      22             : constexpr uint8_t Remb::kFeedbackMessageType;
      23             : // Receiver Estimated Max Bitrate (REMB) (draft-alvestrand-rmcat-remb).
      24             : //
      25             : //     0                   1                   2                   3
      26             : //     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      27             : //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      28             : //    |V=2|P| FMT=15  |   PT=206      |             length            |
      29             : //    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
      30             : //  0 |                  SSRC of packet sender                        |
      31             : //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      32             : //  4 |                       Unused = 0                              |
      33             : //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      34             : //  8 |  Unique identifier 'R' 'E' 'M' 'B'                            |
      35             : //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      36             : // 12 |  Num SSRC     | BR Exp    |  BR Mantissa                      |
      37             : //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      38             : // 16 |   SSRC feedback                                               |
      39             : //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      40             : //    :  ...                                                          :
      41           0 : bool Remb::Parse(const CommonHeader& packet) {
      42           0 :   RTC_DCHECK(packet.type() == kPacketType);
      43           0 :   RTC_DCHECK_EQ(packet.fmt(), kFeedbackMessageType);
      44             : 
      45           0 :   if (packet.payload_size_bytes() < 16) {
      46           0 :     LOG(LS_WARNING) << "Payload length " << packet.payload_size_bytes()
      47           0 :                     << " is too small for Remb packet.";
      48           0 :     return false;
      49             :   }
      50           0 :   const uint8_t* const payload = packet.payload();
      51           0 :   if (kUniqueIdentifier != ByteReader<uint32_t>::ReadBigEndian(&payload[8])) {
      52           0 :     LOG(LS_WARNING) << "REMB identifier not found, not a REMB packet.";
      53           0 :     return false;
      54             :   }
      55           0 :   uint8_t number_of_ssrcs = payload[12];
      56           0 :   if (packet.payload_size_bytes() !=
      57           0 :       kCommonFeedbackLength + (2 + number_of_ssrcs) * 4) {
      58           0 :     LOG(LS_WARNING) << "Payload size " << packet.payload_size_bytes()
      59           0 :                     << " does not match " << number_of_ssrcs << " ssrcs.";
      60           0 :     return false;
      61             :   }
      62             : 
      63           0 :   ParseCommonFeedback(payload);
      64           0 :   uint8_t exponenta = payload[13] >> 2;
      65           0 :   uint64_t mantissa = (static_cast<uint32_t>(payload[13] & 0x03) << 16) |
      66           0 :                       ByteReader<uint16_t>::ReadBigEndian(&payload[14]);
      67           0 :   bitrate_bps_ = (mantissa << exponenta);
      68           0 :   bool shift_overflow = (bitrate_bps_ >> exponenta) != mantissa;
      69           0 :   if (shift_overflow) {
      70           0 :     LOG(LS_ERROR) << "Invalid remb bitrate value : " << mantissa
      71           0 :                   << "*2^" << static_cast<int>(exponenta);
      72           0 :     return false;
      73             :   }
      74             : 
      75           0 :   const uint8_t* next_ssrc = payload + 16;
      76           0 :   ssrcs_.clear();
      77           0 :   ssrcs_.reserve(number_of_ssrcs);
      78           0 :   for (uint8_t i = 0; i < number_of_ssrcs; ++i) {
      79           0 :     ssrcs_.push_back(ByteReader<uint32_t>::ReadBigEndian(next_ssrc));
      80           0 :     next_ssrc += sizeof(uint32_t);
      81             :   }
      82             : 
      83           0 :   return true;
      84             : }
      85             : 
      86           0 : bool Remb::SetSsrcs(std::vector<uint32_t> ssrcs) {
      87           0 :   if (ssrcs.size() > kMaxNumberOfSsrcs) {
      88           0 :     LOG(LS_WARNING) << "Not enough space for all given SSRCs.";
      89           0 :     return false;
      90             :   }
      91           0 :   ssrcs_ = std::move(ssrcs);
      92           0 :   return true;
      93             : }
      94             : 
      95           0 : bool Remb::Create(uint8_t* packet,
      96             :                   size_t* index,
      97             :                   size_t max_length,
      98             :                   RtcpPacket::PacketReadyCallback* callback) const {
      99           0 :   while (*index + BlockLength() > max_length) {
     100           0 :     if (!OnBufferFull(packet, index, callback))
     101           0 :       return false;
     102             :   }
     103           0 :   size_t index_end = *index + BlockLength();
     104           0 :   CreateHeader(kFeedbackMessageType, kPacketType, HeaderLength(), packet,
     105           0 :                index);
     106           0 :   RTC_DCHECK_EQ(0, Psfb::media_ssrc());
     107           0 :   CreateCommonFeedback(packet + *index);
     108           0 :   *index += kCommonFeedbackLength;
     109             : 
     110           0 :   ByteWriter<uint32_t>::WriteBigEndian(packet + *index, kUniqueIdentifier);
     111           0 :   *index += sizeof(uint32_t);
     112           0 :   const uint32_t kMaxMantissa = 0x3ffff;  // 18 bits.
     113           0 :   uint64_t mantissa = bitrate_bps_;
     114           0 :   uint8_t exponenta = 0;
     115           0 :   while (mantissa > kMaxMantissa) {
     116           0 :     mantissa >>= 1;
     117           0 :     ++exponenta;
     118             :   }
     119           0 :   packet[(*index)++] = ssrcs_.size();
     120           0 :   packet[(*index)++] = (exponenta << 2) | (mantissa >> 16);
     121           0 :   ByteWriter<uint16_t>::WriteBigEndian(packet + *index, mantissa & 0xffff);
     122           0 :   *index += sizeof(uint16_t);
     123             : 
     124           0 :   for (uint32_t ssrc : ssrcs_) {
     125           0 :     ByteWriter<uint32_t>::WriteBigEndian(packet + *index, ssrc);
     126           0 :     *index += sizeof(uint32_t);
     127             :   }
     128           0 :   RTC_DCHECK_EQ(index_end, *index);
     129           0 :   return true;
     130             : }
     131             : }  // namespace rtcp
     132             : }  // namespace webrtc

Generated by: LCOV version 1.13