Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Side by Side Diff: webrtc/modules/rtp_rtcp/source/fec_test_helper.cc

Issue 2267393002: Generalize FEC unit tests and rename GenerateFec. (pt. 3) (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@header_reader_writer-pt2-producer_fec_mini_fixes
Patch Set: Rebase after gyp deprecation. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/modules/rtp_rtcp/source/fec_test_helper.h" 11 #include "webrtc/modules/rtp_rtcp/source/fec_test_helper.h"
12 12
13 #include <memory>
14 #include <utility>
15
13 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" 16 #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
14 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" 17 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
15 18
16 namespace webrtc { 19 namespace webrtc {
20 namespace test {
21 namespace fec {
22
23 namespace {
24 constexpr uint8_t kFecPayloadType = 96;
25 constexpr uint8_t kRedPayloadType = 97;
26 constexpr uint8_t kVp8PayloadType = 120;
27 } // namespace
17 28
18 FrameGenerator::FrameGenerator() 29 FrameGenerator::FrameGenerator()
19 : num_packets_(0), seq_num_(0), timestamp_(0) {} 30 : num_packets_(0), seq_num_(0), timestamp_(0) {}
20 31
21 void FrameGenerator::NewFrame(int num_packets) { 32 void FrameGenerator::NewFrame(int num_packets) {
22 num_packets_ = num_packets; 33 num_packets_ = num_packets;
23 timestamp_ += 3000; 34 timestamp_ += 3000;
24 } 35 }
25 36
26 uint16_t FrameGenerator::NextSeqNum() { return ++seq_num_; } 37 uint16_t FrameGenerator::NextSeqNum() { return ++seq_num_; }
27 38
28 test::RawRtpPacket* FrameGenerator::NextPacket(int offset, size_t length) { 39 RawRtpPacket* FrameGenerator::NextPacket(int offset, size_t length) {
29 test::RawRtpPacket* rtp_packet = new test::RawRtpPacket; 40 RawRtpPacket* rtp_packet = new RawRtpPacket;
30 for (size_t i = 0; i < length; ++i) 41 for (size_t i = 0; i < length; ++i)
31 rtp_packet->data[i + kRtpHeaderSize] = offset + i; 42 rtp_packet->data[i + kRtpHeaderSize] = offset + i;
32 rtp_packet->length = length + kRtpHeaderSize; 43 rtp_packet->length = length + kRtpHeaderSize;
33 memset(&rtp_packet->header, 0, sizeof(WebRtcRTPHeader)); 44 memset(&rtp_packet->header, 0, sizeof(WebRtcRTPHeader));
34 rtp_packet->header.frameType = kVideoFrameDelta; 45 rtp_packet->header.frameType = kVideoFrameDelta;
35 rtp_packet->header.header.headerLength = kRtpHeaderSize; 46 rtp_packet->header.header.headerLength = kRtpHeaderSize;
36 rtp_packet->header.header.markerBit = (num_packets_ == 1); 47 rtp_packet->header.header.markerBit = (num_packets_ == 1);
37 rtp_packet->header.header.sequenceNumber = seq_num_; 48 rtp_packet->header.header.sequenceNumber = seq_num_;
38 rtp_packet->header.header.timestamp = timestamp_; 49 rtp_packet->header.header.timestamp = timestamp_;
39 rtp_packet->header.header.payloadType = kVp8PayloadType; 50 rtp_packet->header.header.payloadType = kVp8PayloadType;
40 BuildRtpHeader(rtp_packet->data, &rtp_packet->header.header); 51 BuildRtpHeader(rtp_packet->data, &rtp_packet->header.header);
41 ++seq_num_; 52 ++seq_num_;
42 --num_packets_; 53 --num_packets_;
43 return rtp_packet; 54 return rtp_packet;
44 } 55 }
45 56
46 // Creates a new RtpPacket with the RED header added to the packet. 57 // Creates a new RtpPacket with the RED header added to the packet.
47 test::RawRtpPacket* FrameGenerator::BuildMediaRedPacket( 58 RawRtpPacket* FrameGenerator::BuildMediaRedPacket(const RawRtpPacket* packet) {
48 const test::RawRtpPacket* packet) {
49 const size_t kHeaderLength = packet->header.header.headerLength; 59 const size_t kHeaderLength = packet->header.header.headerLength;
50 test::RawRtpPacket* red_packet = new test::RawRtpPacket; 60 RawRtpPacket* red_packet = new RawRtpPacket;
51 red_packet->header = packet->header; 61 red_packet->header = packet->header;
52 red_packet->length = packet->length + 1; // 1 byte RED header. 62 red_packet->length = packet->length + 1; // 1 byte RED header.
53 memset(red_packet->data, 0, red_packet->length); 63 memset(red_packet->data, 0, red_packet->length);
54 // Copy RTP header. 64 // Copy RTP header.
55 memcpy(red_packet->data, packet->data, kHeaderLength); 65 memcpy(red_packet->data, packet->data, kHeaderLength);
56 SetRedHeader(red_packet, red_packet->data[1] & 0x7f, kHeaderLength); 66 SetRedHeader(red_packet, red_packet->data[1] & 0x7f, kHeaderLength);
57 memcpy(red_packet->data + kHeaderLength + 1, packet->data + kHeaderLength, 67 memcpy(red_packet->data + kHeaderLength + 1, packet->data + kHeaderLength,
58 packet->length - kHeaderLength); 68 packet->length - kHeaderLength);
59 return red_packet; 69 return red_packet;
60 } 70 }
61 71
62 // Creates a new RtpPacket with FEC payload and red header. Does this by 72 // Creates a new RtpPacket with FEC payload and RED header. Does this by
63 // creating a new fake media RtpPacket, clears the marker bit and adds a RED 73 // creating a new fake media RtpPacket, clears the marker bit and adds a RED
64 // header. Finally replaces the payload with the content of |packet->data|. 74 // header. Finally replaces the payload with the content of |packet->data|.
65 test::RawRtpPacket* FrameGenerator::BuildFecRedPacket( 75 RawRtpPacket* FrameGenerator::BuildFecRedPacket(
66 const ForwardErrorCorrection::Packet* packet) { 76 const ForwardErrorCorrection::Packet* packet) {
67 // Create a fake media packet to get a correct header. 1 byte RED header. 77 // Create a fake media packet to get a correct header. 1 byte RED header.
68 ++num_packets_; 78 ++num_packets_;
69 test::RawRtpPacket* red_packet = NextPacket(0, packet->length + 1); 79 RawRtpPacket* red_packet = NextPacket(0, packet->length + 1);
70 red_packet->data[1] &= ~0x80; // Clear marker bit. 80 red_packet->data[1] &= ~0x80; // Clear marker bit.
71 const size_t kHeaderLength = red_packet->header.header.headerLength; 81 const size_t kHeaderLength = red_packet->header.header.headerLength;
72 SetRedHeader(red_packet, kFecPayloadType, kHeaderLength); 82 SetRedHeader(red_packet, kFecPayloadType, kHeaderLength);
73 memcpy(red_packet->data + kHeaderLength + 1, packet->data, packet->length); 83 memcpy(red_packet->data + kHeaderLength + 1, packet->data, packet->length);
74 red_packet->length = kHeaderLength + 1 + packet->length; 84 red_packet->length = kHeaderLength + 1 + packet->length;
75 return red_packet; 85 return red_packet;
76 } 86 }
77 87
78 void FrameGenerator::SetRedHeader(ForwardErrorCorrection::Packet* red_packet, 88 void FrameGenerator::SetRedHeader(ForwardErrorCorrection::Packet* red_packet,
79 uint8_t payload_type, 89 uint8_t payload_type,
80 size_t header_length) const { 90 size_t header_length) const {
81 // Replace pltype. 91 // Replace pltype.
82 red_packet->data[1] &= 0x80; // Reset. 92 red_packet->data[1] &= 0x80; // Reset.
83 red_packet->data[1] += kRedPayloadType; // Replace. 93 red_packet->data[1] += kRedPayloadType; // Replace.
84 94
85 // Add RED header, f-bit always 0. 95 // Add RED header, f-bit always 0.
86 red_packet->data[header_length] = payload_type; 96 red_packet->data[header_length] = payload_type;
87 } 97 }
88 98
89 void FrameGenerator::BuildRtpHeader(uint8_t* data, const RTPHeader* header) { 99 void FrameGenerator::BuildRtpHeader(uint8_t* data, const RTPHeader* header) {
90 data[0] = 0x80; // Version 2. 100 data[0] = 0x80; // Version 2.
91 data[1] = header->payloadType; 101 data[1] = header->payloadType;
92 data[1] |= (header->markerBit ? kRtpMarkerBitMask : 0); 102 data[1] |= (header->markerBit ? kRtpMarkerBitMask : 0);
93 ByteWriter<uint16_t>::WriteBigEndian(data + 2, header->sequenceNumber); 103 ByteWriter<uint16_t>::WriteBigEndian(data + 2, header->sequenceNumber);
94 ByteWriter<uint32_t>::WriteBigEndian(data + 4, header->timestamp); 104 ByteWriter<uint32_t>::WriteBigEndian(data + 4, header->timestamp);
95 ByteWriter<uint32_t>::WriteBigEndian(data + 8, header->ssrc); 105 ByteWriter<uint32_t>::WriteBigEndian(data + 8, header->ssrc);
96 } 106 }
97 107
108 ForwardErrorCorrection::PacketList MediaPacketGenerator::ConstructMediaPackets(
109 int num_media_packets,
110 uint16_t start_seq_num) {
111 RTC_DCHECK_GT(num_media_packets, 0);
112 uint16_t seq_num = start_seq_num;
113 int time_stamp = random_->Rand<int>();
114
115 ForwardErrorCorrection::PacketList media_packets;
116
117 for (int i = 0; i < num_media_packets; ++i) {
118 std::unique_ptr<ForwardErrorCorrection::Packet> media_packet(
119 new ForwardErrorCorrection::Packet());
120 media_packet->length = random_->Rand(min_packet_size_, max_packet_size_);
121
122 // Generate random values for the first 2 bytes
123 media_packet->data[0] = random_->Rand<uint8_t>();
124 media_packet->data[1] = random_->Rand<uint8_t>();
125
126 // The first two bits are assumed to be 10 by the FEC encoder.
127 // In fact the FEC decoder will set the two first bits to 10 regardless of
128 // what they actually were. Set the first two bits to 10 so that a memcmp
129 // can be performed for the whole restored packet.
130 media_packet->data[0] |= 0x80;
131 media_packet->data[0] &= 0xbf;
132
133 // FEC is applied to a whole frame.
134 // A frame is signaled by multiple packets without the marker bit set
135 // followed by the last packet of the frame for which the marker bit is set.
136 // Only push one (fake) frame to the FEC.
137 media_packet->data[1] &= 0x7f;
138
139 webrtc::ByteWriter<uint16_t>::WriteBigEndian(&media_packet->data[2],
140 seq_num);
141 webrtc::ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[4],
142 time_stamp);
143 webrtc::ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[8], ssrc_);
144
145 // Generate random values for payload.
146 for (size_t j = 12; j < media_packet->length; ++j) {
147 media_packet->data[j] = random_->Rand<uint8_t>();
148 }
149 seq_num++;
150 media_packets.push_back(std::move(media_packet));
151 }
152 // Last packet, set marker bit.
153 ForwardErrorCorrection::Packet* media_packet = media_packets.back().get();
154 RTC_DCHECK(media_packet);
155 media_packet->data[1] |= 0x80;
156
157 fec_seq_num_ = seq_num;
158
159 return media_packets;
160 }
161
162 ForwardErrorCorrection::PacketList MediaPacketGenerator::ConstructMediaPackets(
163 int num_media_packets) {
164 return ConstructMediaPackets(num_media_packets, random_->Rand<uint16_t>());
165 }
166
167 uint16_t MediaPacketGenerator::GetFecSeqNum() {
168 return fec_seq_num_;
169 }
170
171 } // namespace fec
172 } // namespace test
98 } // namespace webrtc 173 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/rtp_rtcp/source/fec_test_helper.h ('k') | webrtc/modules/rtp_rtcp/source/forward_error_correction.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698