blob: 6ed6f987555f3fccef0a1a4bdc83808f3ea0dadd [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "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
Tommi25eb47c2019-08-29 16:39:05 +020017#include "modules/rtp_rtcp/source/rtp_utility.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "rtc_base/checks.h"
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000019
20namespace webrtc {
21namespace test {
22
Tommi25eb47c2019-08-29 16:39:05 +020023using webrtc::RtpUtility::RtpHeaderParser;
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000024
25Packet::Packet(uint8_t* packet_memory,
26 size_t allocated_bytes,
27 size_t virtual_packet_length_bytes,
28 double time_ms,
Tommi25eb47c2019-08-29 16:39:05 +020029 const RtpUtility::RtpHeaderParser& parser,
30 const RtpHeaderExtensionMap* extension_map /*= nullptr*/)
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000031 : payload_memory_(packet_memory),
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000032 packet_length_bytes_(allocated_bytes),
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000033 virtual_packet_length_bytes_(virtual_packet_length_bytes),
34 virtual_payload_length_bytes_(0),
Tommi25eb47c2019-08-29 16:39:05 +020035 time_ms_(time_ms),
36 valid_header_(ParseHeader(parser, extension_map)) {}
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000037
Bjorn Terelius5350d1c2018-10-11 16:51:23 +020038Packet::Packet(const RTPHeader& header,
39 size_t virtual_packet_length_bytes,
40 size_t virtual_payload_length_bytes,
41 double time_ms)
42 : header_(header),
Bjorn Terelius5350d1c2018-10-11 16:51:23 +020043 virtual_packet_length_bytes_(virtual_packet_length_bytes),
44 virtual_payload_length_bytes_(virtual_payload_length_bytes),
45 time_ms_(time_ms),
46 valid_header_(true) {}
47
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000048Packet::Packet(uint8_t* packet_memory, size_t allocated_bytes, double time_ms)
Tommi25eb47c2019-08-29 16:39:05 +020049 : Packet(packet_memory,
50 allocated_bytes,
51 allocated_bytes,
52 time_ms,
53 RtpUtility::RtpHeaderParser(packet_memory, allocated_bytes)) {}
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000054
55Packet::Packet(uint8_t* packet_memory,
56 size_t allocated_bytes,
57 size_t virtual_packet_length_bytes,
58 double time_ms)
Tommi25eb47c2019-08-29 16:39:05 +020059 : Packet(packet_memory,
60 allocated_bytes,
61 virtual_packet_length_bytes,
62 time_ms,
63 RtpUtility::RtpHeaderParser(packet_memory, allocated_bytes)) {}
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000064
kwibergb8e56ee2016-08-29 06:37:33 -070065Packet::~Packet() = default;
66
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000067bool Packet::ExtractRedHeaders(std::list<RTPHeader*>* headers) const {
68 //
69 // 0 1 2 3
70 // 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
71 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
72 // |1| block PT | timestamp offset | block length |
73 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
74 // |1| ... |
75 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
76 // |0| block PT |
77 // +-+-+-+-+-+-+-+-+
78 //
79
80 assert(payload_);
81 const uint8_t* payload_ptr = payload_;
82 const uint8_t* payload_end_ptr = payload_ptr + payload_length_bytes_;
83
84 // Find all RED headers with the extension bit set to 1. That is, all headers
85 // but the last one.
86 while ((payload_ptr < payload_end_ptr) && (*payload_ptr & 0x80)) {
87 RTPHeader* header = new RTPHeader;
88 CopyToHeader(header);
89 header->payloadType = payload_ptr[0] & 0x7F;
90 uint32_t offset = (payload_ptr[1] << 6) + ((payload_ptr[2] & 0xFC) >> 2);
91 header->timestamp -= offset;
92 headers->push_front(header);
93 payload_ptr += 4;
94 }
95 // Last header.
96 assert(payload_ptr < payload_end_ptr);
97 if (payload_ptr >= payload_end_ptr) {
98 return false; // Payload too short.
99 }
100 RTPHeader* header = new RTPHeader;
101 CopyToHeader(header);
102 header->payloadType = payload_ptr[0] & 0x7F;
103 headers->push_front(header);
104 return true;
105}
106
107void Packet::DeleteRedHeaders(std::list<RTPHeader*>* headers) {
108 while (!headers->empty()) {
109 delete headers->front();
110 headers->pop_front();
111 }
112}
113
Tommi25eb47c2019-08-29 16:39:05 +0200114bool Packet::ParseHeader(const RtpHeaderParser& parser,
115 const RtpHeaderExtensionMap* extension_map) {
116 bool valid_header = parser.Parse(&header_, extension_map);
117
henrik.lundin7a2862a2017-06-01 07:41:11 -0700118 // Special case for dummy packets that have padding marked in the RTP header.
119 // This causes the RTP header parser to report failure, but is fine in this
120 // context.
121 const bool header_only_with_padding =
122 (header_.headerLength == packet_length_bytes_ &&
123 header_.paddingLength > 0);
124 if (!valid_header && !header_only_with_padding) {
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +0000125 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;
henrik.lundind1a10a02016-08-24 10:58:54 -0700131 RTC_CHECK_GE(virtual_packet_length_bytes_, packet_length_bytes_);
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +0000132 assert(virtual_packet_length_bytes_ >= header_.headerLength);
133 virtual_payload_length_bytes_ =
134 virtual_packet_length_bytes_ - header_.headerLength;
135 return true;
136}
137
138void Packet::CopyToHeader(RTPHeader* destination) const {
Niels Möllera533e002019-03-26 13:14:30 +0100139 *destination = header_;
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +0000140}
141
142} // namespace test
143} // namespace webrtc