2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
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.
11 #include "webrtc/modules/audio_coding/neteq4/tools/packet.h"
12 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
17 Packet::Packet(uint8_t* packet_memory,
18 size_t allocated_bytes,
20 const RtpHeaderParser& parser)
21 : payload_memory_(packet_memory),
23 packet_length_bytes_(allocated_bytes),
24 payload_length_bytes_(0),
25 virtual_packet_length_bytes_(allocated_bytes),
26 virtual_payload_length_bytes_(0),
28 valid_header_ = ParseHeader(parser);
31 Packet::Packet(uint8_t* packet_memory,
32 size_t allocated_bytes,
33 size_t virtual_packet_length_bytes,
35 const RtpHeaderParser& parser)
36 : payload_memory_(packet_memory),
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),
43 valid_header_ = ParseHeader(parser);
46 Packet::Packet(uint8_t* packet_memory, size_t allocated_bytes, double time_ms)
47 : payload_memory_(packet_memory),
49 packet_length_bytes_(allocated_bytes),
50 payload_length_bytes_(0),
51 virtual_packet_length_bytes_(allocated_bytes),
52 virtual_payload_length_bytes_(0),
54 scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
55 valid_header_ = ParseHeader(*parser);
58 Packet::Packet(uint8_t* packet_memory,
59 size_t allocated_bytes,
60 size_t virtual_packet_length_bytes,
62 : payload_memory_(packet_memory),
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),
69 scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
70 valid_header_ = ParseHeader(*parser);
73 bool Packet::ExtractRedHeaders(std::list<RTPHeader*>* headers) const {
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 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
81 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
87 const uint8_t* payload_ptr = payload_;
88 const uint8_t* payload_end_ptr = payload_ptr + payload_length_bytes_;
90 // Find all RED headers with the extension bit set to 1. That is, all headers
92 while ((payload_ptr < payload_end_ptr) && (*payload_ptr & 0x80)) {
93 RTPHeader* header = new RTPHeader;
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);
102 assert(payload_ptr < payload_end_ptr);
103 if (payload_ptr >= payload_end_ptr) {
104 return false; // Payload too short.
106 RTPHeader* header = new RTPHeader;
107 CopyToHeader(header);
108 header->payloadType = payload_ptr[0] & 0x7F;
109 headers->push_front(header);
113 void Packet::DeleteRedHeaders(std::list<RTPHeader*>* headers) {
114 while (!headers->empty()) {
115 delete headers->front();
116 headers->pop_front();
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);
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;
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,
149 sizeof(header_.arrOfCSRCs));
151 &destination->extension, &header_.extension, sizeof(header_.extension));
155 } // namespace webrtc