LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtcp_packet - rpsi.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 65 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/source/rtcp_packet/rpsi.h"
      12             : 
      13             : #include "webrtc/base/checks.h"
      14             : #include "webrtc/base/logging.h"
      15             : #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
      16             : #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/common_header.h"
      17             : #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
      18             : 
      19             : using webrtc::RtpUtility::Word32Align;
      20             : 
      21             : namespace webrtc {
      22             : namespace rtcp {
      23             : constexpr uint8_t Rpsi::kFeedbackMessageType;
      24             : // RFC 4585: Feedback format.
      25             : // Reference picture selection indication (RPSI) (RFC 4585).
      26             : //
      27             : //     0                   1                   2                   3
      28             : //     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
      29             : //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      30             : //    |V=2|P| RPSI=3  |  PT=PSFB=206  |          length               |
      31             : //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      32             : //  0 |                  SSRC of packet sender                        |
      33             : //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      34             : //  4 |                  SSRC of media source                         |
      35             : //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      36             : //  8 | Padding Bits  |
      37             : //  9                 |0| Payload Type|
      38             : // 10                                 |  Native RPSI bit string       :
      39             : //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      40             : //    :   defined per codec          ...                | Padding (0) |
      41             : //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      42             : namespace {
      43             : constexpr size_t kPaddingSizeOffset = 8;
      44             : constexpr size_t kPayloadTypeOffset = 9;
      45             : constexpr size_t kBitStringOffset = 10;
      46             : 
      47             : constexpr size_t kPidBits = 7;
      48             : // Calculates number of bytes required to store given picture id.
      49           0 : uint8_t RequiredBytes(uint64_t picture_id) {
      50           0 :   uint8_t required_bytes = 0;
      51           0 :   uint64_t shifted_pid = picture_id;
      52           0 :   do {
      53           0 :     ++required_bytes;
      54           0 :     shifted_pid >>= kPidBits;
      55           0 :   } while (shifted_pid > 0);
      56             : 
      57           0 :   return required_bytes;
      58             : }
      59             : }  // namespace
      60             : 
      61           0 : Rpsi::Rpsi()
      62             :     : payload_type_(0),
      63             :       picture_id_(0),
      64           0 :       block_length_(CalculateBlockLength(1)) {}
      65             : 
      66           0 : bool Rpsi::Parse(const CommonHeader& packet) {
      67           0 :   RTC_DCHECK_EQ(packet.type(), kPacketType);
      68           0 :   RTC_DCHECK_EQ(packet.fmt(), kFeedbackMessageType);
      69             : 
      70           0 :   if (packet.payload_size_bytes() < kCommonFeedbackLength + 4) {
      71           0 :     LOG(LS_WARNING) << "Packet is too small to be a valid RPSI packet.";
      72           0 :     return false;
      73             :   }
      74             : 
      75           0 :   ParseCommonFeedback(packet.payload());
      76             : 
      77           0 :   uint8_t padding_bits = packet.payload()[kPaddingSizeOffset];
      78           0 :   if (padding_bits % 8 != 0) {
      79           0 :     LOG(LS_WARNING) << "Unknown rpsi packet with fractional number of bytes.";
      80           0 :     return false;
      81             :   }
      82           0 :   size_t padding_bytes = padding_bits / 8;
      83           0 :   if (padding_bytes + kBitStringOffset >= packet.payload_size_bytes()) {
      84           0 :     LOG(LS_WARNING) << "Too many padding bytes in a RPSI packet.";
      85           0 :     return false;
      86             :   }
      87           0 :   size_t padding_offset = packet.payload_size_bytes() - padding_bytes;
      88           0 :   payload_type_ = packet.payload()[kPayloadTypeOffset] & 0x7f;
      89           0 :   picture_id_ = 0;
      90           0 :   for (size_t pos = kBitStringOffset; pos < padding_offset; ++pos) {
      91           0 :     picture_id_ <<= kPidBits;
      92           0 :     picture_id_ |= (packet.payload()[pos] & 0x7f);
      93             :   }
      94             :   // Required bytes might become less than came in the packet.
      95           0 :   block_length_ = CalculateBlockLength(RequiredBytes(picture_id_));
      96           0 :   return true;
      97             : }
      98             : 
      99           0 : bool Rpsi::Create(uint8_t* packet,
     100             :                   size_t* index,
     101             :                   size_t max_length,
     102             :                   RtcpPacket::PacketReadyCallback* callback) const {
     103           0 :   while (*index + BlockLength() > max_length) {
     104           0 :     if (!OnBufferFull(packet, index, callback))
     105           0 :       return false;
     106             :   }
     107           0 :   size_t index_end = *index + BlockLength();
     108             : 
     109           0 :   CreateHeader(kFeedbackMessageType, kPacketType, HeaderLength(), packet,
     110           0 :                index);
     111           0 :   CreateCommonFeedback(packet + *index);
     112           0 :   *index += kCommonFeedbackLength;
     113             : 
     114           0 :   size_t bitstring_size_bytes = RequiredBytes(picture_id_);
     115             :   size_t padding_bytes =
     116           0 :       Word32Align(2 + bitstring_size_bytes) - (2 + bitstring_size_bytes);
     117           0 :   packet[(*index)++] = padding_bytes * 8;
     118           0 :   packet[(*index)++] = payload_type_;
     119             : 
     120             :   // Convert picture id to native bit string (defined by the video codec).
     121           0 :   for (size_t i = bitstring_size_bytes - 1; i > 0; --i) {
     122           0 :     packet[(*index)++] =
     123           0 :         0x80 | static_cast<uint8_t>(picture_id_ >> (i * kPidBits));
     124             :   }
     125           0 :   packet[(*index)++] = static_cast<uint8_t>(picture_id_ & 0x7f);
     126           0 :   constexpr uint8_t kPadding = 0;
     127           0 :   for (size_t i = 0; i < padding_bytes; ++i)
     128           0 :     packet[(*index)++] = kPadding;
     129           0 :   RTC_CHECK_EQ(*index, index_end);
     130           0 :   return true;
     131             : }
     132             : 
     133           0 : void Rpsi::SetPayloadType(uint8_t payload) {
     134           0 :   RTC_DCHECK_LE(payload, 0x7f);
     135           0 :   payload_type_ = payload;
     136           0 : }
     137             : 
     138           0 : void Rpsi::SetPictureId(uint64_t picture_id) {
     139           0 :   picture_id_ = picture_id;
     140           0 :   block_length_ = CalculateBlockLength(RequiredBytes(picture_id_));
     141           0 : }
     142             : 
     143           0 : size_t Rpsi::CalculateBlockLength(uint8_t bitstring_size_bytes) {
     144             :   return RtcpPacket::kHeaderLength + Psfb::kCommonFeedbackLength +
     145           0 :          Word32Align(2 + bitstring_size_bytes);
     146             : }
     147             : }  // namespace rtcp
     148             : }  // namespace webrtc

Generated by: LCOV version 1.13