Home | History | Annotate | Download | only in tools
      1 /*
      2  *  Copyright (c) 2014 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/audio_coding/neteq/tools/packet.h"
     12 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
     13 
     14 namespace webrtc {
     15 namespace test {
     16 
     17 Packet::Packet(uint8_t* packet_memory,
     18                size_t allocated_bytes,
     19                double time_ms,
     20                const RtpHeaderParser& parser)
     21     : payload_memory_(packet_memory),
     22       payload_(NULL),
     23       packet_length_bytes_(allocated_bytes),
     24       payload_length_bytes_(0),
     25       virtual_packet_length_bytes_(allocated_bytes),
     26       virtual_payload_length_bytes_(0),
     27       time_ms_(time_ms) {
     28   valid_header_ = ParseHeader(parser);
     29 }
     30 
     31 Packet::Packet(uint8_t* packet_memory,
     32                size_t allocated_bytes,
     33                size_t virtual_packet_length_bytes,
     34                double time_ms,
     35                const RtpHeaderParser& parser)
     36     : payload_memory_(packet_memory),
     37       payload_(NULL),
     38       packet_length_bytes_(allocated_bytes),
     39       payload_length_bytes_(0),
     40       virtual_packet_length_bytes_(virtual_packet_length_bytes),
     41       virtual_payload_length_bytes_(0),
     42       time_ms_(time_ms) {
     43   valid_header_ = ParseHeader(parser);
     44 }
     45 
     46 Packet::Packet(uint8_t* packet_memory, size_t allocated_bytes, double time_ms)
     47     : payload_memory_(packet_memory),
     48       payload_(NULL),
     49       packet_length_bytes_(allocated_bytes),
     50       payload_length_bytes_(0),
     51       virtual_packet_length_bytes_(allocated_bytes),
     52       virtual_payload_length_bytes_(0),
     53       time_ms_(time_ms) {
     54   scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
     55   valid_header_ = ParseHeader(*parser);
     56 }
     57 
     58 Packet::Packet(uint8_t* packet_memory,
     59                size_t allocated_bytes,
     60                size_t virtual_packet_length_bytes,
     61                double time_ms)
     62     : payload_memory_(packet_memory),
     63       payload_(NULL),
     64       packet_length_bytes_(allocated_bytes),
     65       payload_length_bytes_(0),
     66       virtual_packet_length_bytes_(virtual_packet_length_bytes),
     67       virtual_payload_length_bytes_(0),
     68       time_ms_(time_ms) {
     69   scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
     70   valid_header_ = ParseHeader(*parser);
     71 }
     72 
     73 bool Packet::ExtractRedHeaders(std::list<RTPHeader*>* headers) const {
     74   //
     75   //  0                   1                    2                   3
     76   //  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
     77   // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     78   // |1|   block PT  |  timestamp offset         |   block length    |
     79   // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     80   // |1|    ...                                                      |
     81   // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     82   // |0|   block PT  |
     83   // +-+-+-+-+-+-+-+-+
     84   //
     85 
     86   assert(payload_);
     87   const uint8_t* payload_ptr = payload_;
     88   const uint8_t* payload_end_ptr = payload_ptr + payload_length_bytes_;
     89 
     90   // Find all RED headers with the extension bit set to 1. That is, all headers
     91   // but the last one.
     92   while ((payload_ptr < payload_end_ptr) && (*payload_ptr & 0x80)) {
     93     RTPHeader* header = new RTPHeader;
     94     CopyToHeader(header);
     95     header->payloadType = payload_ptr[0] & 0x7F;
     96     uint32_t offset = (payload_ptr[1] << 6) + ((payload_ptr[2] & 0xFC) >> 2);
     97     header->timestamp -= offset;
     98     headers->push_front(header);
     99     payload_ptr += 4;
    100   }
    101   // Last header.
    102   assert(payload_ptr < payload_end_ptr);
    103   if (payload_ptr >= payload_end_ptr) {
    104     return false;  // Payload too short.
    105   }
    106   RTPHeader* header = new RTPHeader;
    107   CopyToHeader(header);
    108   header->payloadType = payload_ptr[0] & 0x7F;
    109   headers->push_front(header);
    110   return true;
    111 }
    112 
    113 void Packet::DeleteRedHeaders(std::list<RTPHeader*>* headers) {
    114   while (!headers->empty()) {
    115     delete headers->front();
    116     headers->pop_front();
    117   }
    118 }
    119 
    120 bool Packet::ParseHeader(const RtpHeaderParser& parser) {
    121   bool valid_header = parser.Parse(
    122       payload_memory_.get(), static_cast<int>(packet_length_bytes_), &header_);
    123   assert(valid_header);
    124   if (!valid_header) {
    125     return false;
    126   }
    127   assert(header_.headerLength <= packet_length_bytes_);
    128   payload_ = &payload_memory_[header_.headerLength];
    129   assert(packet_length_bytes_ >= header_.headerLength);
    130   payload_length_bytes_ = packet_length_bytes_ - header_.headerLength;
    131   assert(virtual_packet_length_bytes_ >= header_.headerLength);
    132   virtual_payload_length_bytes_ =
    133       virtual_packet_length_bytes_ - header_.headerLength;
    134   return true;
    135 }
    136 
    137 void Packet::CopyToHeader(RTPHeader* destination) const {
    138   destination->markerBit = header_.markerBit;
    139   destination->payloadType = header_.payloadType;
    140   destination->sequenceNumber = header_.sequenceNumber;
    141   destination->timestamp = header_.timestamp;
    142   destination->ssrc = header_.ssrc;
    143   destination->numCSRCs = header_.numCSRCs;
    144   destination->paddingLength = header_.paddingLength;
    145   destination->headerLength = header_.headerLength;
    146   destination->payload_type_frequency = header_.payload_type_frequency;
    147   memcpy(&destination->arrOfCSRCs,
    148          &header_.arrOfCSRCs,
    149          sizeof(header_.arrOfCSRCs));
    150   memcpy(
    151       &destination->extension, &header_.extension, sizeof(header_.extension));
    152 }
    153 
    154 }  // namespace test
    155 }  // namespace webrtc
    156