blob: e540173f43a83fa22d73a5dd0275f15a3af56b6a [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
Danil Chapovalovb4100ad2021-06-16 14:23:22 +020013#include "api/array_view.h"
14#include "modules/rtp_rtcp/source/rtp_packet_received.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "rtc_base/checks.h"
Danil Chapovalovb4100ad2021-06-16 14:23:22 +020016#include "rtc_base/copy_on_write_buffer.h"
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000017
18namespace webrtc {
19namespace test {
20
Danil Chapovalovb4100ad2021-06-16 14:23:22 +020021Packet::Packet(rtc::CopyOnWriteBuffer packet,
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000022 size_t virtual_packet_length_bytes,
23 double time_ms,
Danil Chapovalovb4100ad2021-06-16 14:23:22 +020024 const RtpHeaderExtensionMap* extension_map)
25 : packet_(std::move(packet)),
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000026 virtual_packet_length_bytes_(virtual_packet_length_bytes),
Tommi25eb47c2019-08-29 16:39:05 +020027 time_ms_(time_ms),
Danil Chapovalovb4100ad2021-06-16 14:23:22 +020028 valid_header_(ParseHeader(extension_map)) {}
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000029
Bjorn Terelius5350d1c2018-10-11 16:51:23 +020030Packet::Packet(const RTPHeader& header,
31 size_t virtual_packet_length_bytes,
32 size_t virtual_payload_length_bytes,
33 double time_ms)
34 : header_(header),
Bjorn Terelius5350d1c2018-10-11 16:51:23 +020035 virtual_packet_length_bytes_(virtual_packet_length_bytes),
36 virtual_payload_length_bytes_(virtual_payload_length_bytes),
37 time_ms_(time_ms),
38 valid_header_(true) {}
39
kwibergb8e56ee2016-08-29 06:37:33 -070040Packet::~Packet() = default;
41
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000042bool Packet::ExtractRedHeaders(std::list<RTPHeader*>* headers) const {
43 //
44 // 0 1 2 3
45 // 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
46 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47 // |1| block PT | timestamp offset | block length |
48 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
49 // |1| ... |
50 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
51 // |0| block PT |
52 // +-+-+-+-+-+-+-+-+
53 //
54
Danil Chapovalovb4100ad2021-06-16 14:23:22 +020055 const uint8_t* payload_ptr = payload();
56 const uint8_t* payload_end_ptr = payload_ptr + payload_length_bytes();
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000057
58 // Find all RED headers with the extension bit set to 1. That is, all headers
59 // but the last one.
60 while ((payload_ptr < payload_end_ptr) && (*payload_ptr & 0x80)) {
61 RTPHeader* header = new RTPHeader;
62 CopyToHeader(header);
63 header->payloadType = payload_ptr[0] & 0x7F;
64 uint32_t offset = (payload_ptr[1] << 6) + ((payload_ptr[2] & 0xFC) >> 2);
65 header->timestamp -= offset;
66 headers->push_front(header);
67 payload_ptr += 4;
68 }
69 // Last header.
Jerome Humbert9338bbc2019-12-12 20:49:33 +000070 RTC_DCHECK_LT(payload_ptr, payload_end_ptr);
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000071 if (payload_ptr >= payload_end_ptr) {
72 return false; // Payload too short.
73 }
74 RTPHeader* header = new RTPHeader;
75 CopyToHeader(header);
76 header->payloadType = payload_ptr[0] & 0x7F;
77 headers->push_front(header);
78 return true;
79}
80
81void Packet::DeleteRedHeaders(std::list<RTPHeader*>* headers) {
82 while (!headers->empty()) {
83 delete headers->front();
84 headers->pop_front();
85 }
86}
87
Danil Chapovalovb4100ad2021-06-16 14:23:22 +020088bool Packet::ParseHeader(const RtpHeaderExtensionMap* extension_map) {
89 // Use RtpPacketReceived instead of RtpPacket because former already has a
90 // converter into legacy RTPHeader.
91 webrtc::RtpPacketReceived rtp_packet(extension_map);
Tommi25eb47c2019-08-29 16:39:05 +020092
Danil Chapovalovb4100ad2021-06-16 14:23:22 +020093 // Because of the special case of dummy packets that have padding marked in
94 // the RTP header, but do not have rtp payload with the padding size, handle
95 // padding manually. Regular RTP packet parser reports failure, but it is fine
96 // in this context.
97 bool padding = (packet_[0] & 0b0010'0000);
98 size_t padding_size = 0;
99 if (padding) {
100 // Clear the padding bit to prevent failure when rtp payload is omited.
101 rtc::CopyOnWriteBuffer packet(packet_);
102 packet.MutableData()[0] &= ~0b0010'0000;
103 if (!rtp_packet.Parse(std::move(packet))) {
104 return false;
105 }
106 if (rtp_packet.payload_size() > 0) {
107 padding_size = rtp_packet.data()[rtp_packet.size() - 1];
108 }
109 if (padding_size > rtp_packet.payload_size()) {
110 return false;
111 }
112 } else {
113 if (!rtp_packet.Parse(packet_)) {
114 return false;
115 }
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +0000116 }
Danil Chapovalovb4100ad2021-06-16 14:23:22 +0200117 rtp_payload_ = rtc::MakeArrayView(packet_.data() + rtp_packet.headers_size(),
118 rtp_packet.payload_size() - padding_size);
119 rtp_packet.GetHeader(&header_);
120
121 RTC_CHECK_GE(virtual_packet_length_bytes_, rtp_packet.size());
122 RTC_DCHECK_GE(virtual_packet_length_bytes_, rtp_packet.headers_size());
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +0000123 virtual_payload_length_bytes_ =
Danil Chapovalovb4100ad2021-06-16 14:23:22 +0200124 virtual_packet_length_bytes_ - rtp_packet.headers_size();
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +0000125 return true;
126}
127
128void Packet::CopyToHeader(RTPHeader* destination) const {
Niels Möllera533e002019-03-26 13:14:30 +0100129 *destination = header_;
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +0000130}
131
132} // namespace test
133} // namespace webrtc