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