blob: 46fd0cbc8cd531a1ea6b8d7d4a684388bdeeb3e2 [file] [log] [blame]
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +00001/*
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
henrik.lundin@webrtc.org9c55f0f2014-06-09 08:10:28 +000011#include "webrtc/modules/audio_coding/neteq/tools/packet.h"
henrik.lundin@webrtc.org1c839122014-08-11 12:29:38 +000012
13#include <string.h>
14
kwiberg2d0c3322016-02-14 09:28:33 -080015#include <memory>
16
Henrik Kjellanderff761fb2015-11-04 08:31:52 +010017#include "webrtc/modules/include/module_common_types.h"
18#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000019
20namespace webrtc {
21namespace test {
22
23Packet::Packet(uint8_t* packet_memory,
24 size_t allocated_bytes,
25 double time_ms,
26 const RtpHeaderParser& parser)
27 : payload_memory_(packet_memory),
28 payload_(NULL),
29 packet_length_bytes_(allocated_bytes),
30 payload_length_bytes_(0),
31 virtual_packet_length_bytes_(allocated_bytes),
32 virtual_payload_length_bytes_(0),
33 time_ms_(time_ms) {
34 valid_header_ = ParseHeader(parser);
35}
36
37Packet::Packet(uint8_t* packet_memory,
38 size_t allocated_bytes,
39 size_t virtual_packet_length_bytes,
40 double time_ms,
41 const RtpHeaderParser& parser)
42 : payload_memory_(packet_memory),
43 payload_(NULL),
44 packet_length_bytes_(allocated_bytes),
45 payload_length_bytes_(0),
46 virtual_packet_length_bytes_(virtual_packet_length_bytes),
47 virtual_payload_length_bytes_(0),
48 time_ms_(time_ms) {
49 valid_header_ = ParseHeader(parser);
50}
51
52Packet::Packet(uint8_t* packet_memory, size_t allocated_bytes, double time_ms)
53 : payload_memory_(packet_memory),
54 payload_(NULL),
55 packet_length_bytes_(allocated_bytes),
56 payload_length_bytes_(0),
57 virtual_packet_length_bytes_(allocated_bytes),
58 virtual_payload_length_bytes_(0),
59 time_ms_(time_ms) {
kwiberg2d0c3322016-02-14 09:28:33 -080060 std::unique_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000061 valid_header_ = ParseHeader(*parser);
62}
63
64Packet::Packet(uint8_t* packet_memory,
65 size_t allocated_bytes,
66 size_t virtual_packet_length_bytes,
67 double time_ms)
68 : payload_memory_(packet_memory),
69 payload_(NULL),
70 packet_length_bytes_(allocated_bytes),
71 payload_length_bytes_(0),
72 virtual_packet_length_bytes_(virtual_packet_length_bytes),
73 virtual_payload_length_bytes_(0),
74 time_ms_(time_ms) {
kwiberg2d0c3322016-02-14 09:28:33 -080075 std::unique_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000076 valid_header_ = ParseHeader(*parser);
77}
78
79bool Packet::ExtractRedHeaders(std::list<RTPHeader*>* headers) const {
80 //
81 // 0 1 2 3
82 // 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
83 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
84 // |1| block PT | timestamp offset | block length |
85 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
86 // |1| ... |
87 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
88 // |0| block PT |
89 // +-+-+-+-+-+-+-+-+
90 //
91
92 assert(payload_);
93 const uint8_t* payload_ptr = payload_;
94 const uint8_t* payload_end_ptr = payload_ptr + payload_length_bytes_;
95
96 // Find all RED headers with the extension bit set to 1. That is, all headers
97 // but the last one.
98 while ((payload_ptr < payload_end_ptr) && (*payload_ptr & 0x80)) {
99 RTPHeader* header = new RTPHeader;
100 CopyToHeader(header);
101 header->payloadType = payload_ptr[0] & 0x7F;
102 uint32_t offset = (payload_ptr[1] << 6) + ((payload_ptr[2] & 0xFC) >> 2);
103 header->timestamp -= offset;
104 headers->push_front(header);
105 payload_ptr += 4;
106 }
107 // Last header.
108 assert(payload_ptr < payload_end_ptr);
109 if (payload_ptr >= payload_end_ptr) {
110 return false; // Payload too short.
111 }
112 RTPHeader* header = new RTPHeader;
113 CopyToHeader(header);
114 header->payloadType = payload_ptr[0] & 0x7F;
115 headers->push_front(header);
116 return true;
117}
118
119void Packet::DeleteRedHeaders(std::list<RTPHeader*>* headers) {
120 while (!headers->empty()) {
121 delete headers->front();
122 headers->pop_front();
123 }
124}
125
henrik.lundin@webrtc.org1c839122014-08-11 12:29:38 +0000126void Packet::ConvertHeader(WebRtcRTPHeader* copy_to) const {
127 memcpy(&copy_to->header, &header_, sizeof(header_));
128 copy_to->frameType = kAudioFrameSpeech;
129 copy_to->type.Audio.numEnergy = 0;
130 copy_to->type.Audio.channel = 1;
131 copy_to->type.Audio.isCNG = false;
132}
133
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +0000134bool Packet::ParseHeader(const RtpHeaderParser& parser) {
135 bool valid_header = parser.Parse(
136 payload_memory_.get(), static_cast<int>(packet_length_bytes_), &header_);
137 assert(valid_header);
138 if (!valid_header) {
139 return false;
140 }
141 assert(header_.headerLength <= packet_length_bytes_);
142 payload_ = &payload_memory_[header_.headerLength];
143 assert(packet_length_bytes_ >= header_.headerLength);
144 payload_length_bytes_ = packet_length_bytes_ - header_.headerLength;
145 assert(virtual_packet_length_bytes_ >= header_.headerLength);
146 virtual_payload_length_bytes_ =
147 virtual_packet_length_bytes_ - header_.headerLength;
148 return true;
149}
150
151void Packet::CopyToHeader(RTPHeader* destination) const {
152 destination->markerBit = header_.markerBit;
153 destination->payloadType = header_.payloadType;
154 destination->sequenceNumber = header_.sequenceNumber;
155 destination->timestamp = header_.timestamp;
156 destination->ssrc = header_.ssrc;
157 destination->numCSRCs = header_.numCSRCs;
158 destination->paddingLength = header_.paddingLength;
159 destination->headerLength = header_.headerLength;
160 destination->payload_type_frequency = header_.payload_type_frequency;
161 memcpy(&destination->arrOfCSRCs,
162 &header_.arrOfCSRCs,
163 sizeof(header_.arrOfCSRCs));
164 memcpy(
165 &destination->extension, &header_.extension, sizeof(header_.extension));
166}
167
168} // namespace test
169} // namespace webrtc