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