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

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: 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
19 namespace {
20
21 constexpr uint8_t kFecPayloadType = 96;
22 constexpr uint8_t kRedPayloadType = 97;
23 constexpr uint8_t kVp8PayloadType = 120;
24
25 } // namespace
26
16 namespace webrtc { 27 namespace webrtc {
28 namespace test {
29 namespace fec {
17 30
18 FrameGenerator::FrameGenerator() 31 FrameGenerator::FrameGenerator()
19 : num_packets_(0), seq_num_(0), timestamp_(0) {} 32 : num_packets_(0), seq_num_(0), timestamp_(0) {}
20 33
21 void FrameGenerator::NewFrame(int num_packets) { 34 void FrameGenerator::NewFrame(int num_packets) {
22 num_packets_ = num_packets; 35 num_packets_ = num_packets;
23 timestamp_ += 3000; 36 timestamp_ += 3000;
24 } 37 }
25 38
26 uint16_t FrameGenerator::NextSeqNum() { return ++seq_num_; } 39 uint16_t FrameGenerator::NextSeqNum() { return ++seq_num_; }
27 40
28 test::RawRtpPacket* FrameGenerator::NextPacket(int offset, size_t length) { 41 RawRtpPacket* FrameGenerator::NextPacket(int offset, size_t length) {
29 test::RawRtpPacket* rtp_packet = new test::RawRtpPacket; 42 RawRtpPacket* rtp_packet = new RawRtpPacket;
30 for (size_t i = 0; i < length; ++i) 43 for (size_t i = 0; i < length; ++i)
31 rtp_packet->data[i + kRtpHeaderSize] = offset + i; 44 rtp_packet->data[i + kRtpHeaderSize] = offset + i;
32 rtp_packet->length = length + kRtpHeaderSize; 45 rtp_packet->length = length + kRtpHeaderSize;
33 memset(&rtp_packet->header, 0, sizeof(WebRtcRTPHeader)); 46 memset(&rtp_packet->header, 0, sizeof(WebRtcRTPHeader));
34 rtp_packet->header.frameType = kVideoFrameDelta; 47 rtp_packet->header.frameType = kVideoFrameDelta;
35 rtp_packet->header.header.headerLength = kRtpHeaderSize; 48 rtp_packet->header.header.headerLength = kRtpHeaderSize;
36 rtp_packet->header.header.markerBit = (num_packets_ == 1); 49 rtp_packet->header.header.markerBit = (num_packets_ == 1);
37 rtp_packet->header.header.sequenceNumber = seq_num_; 50 rtp_packet->header.header.sequenceNumber = seq_num_;
38 rtp_packet->header.header.timestamp = timestamp_; 51 rtp_packet->header.header.timestamp = timestamp_;
39 rtp_packet->header.header.payloadType = kVp8PayloadType; 52 rtp_packet->header.header.payloadType = kVp8PayloadType;
40 BuildRtpHeader(rtp_packet->data, &rtp_packet->header.header); 53 BuildRtpHeader(rtp_packet->data, &rtp_packet->header.header);
41 ++seq_num_; 54 ++seq_num_;
42 --num_packets_; 55 --num_packets_;
43 return rtp_packet; 56 return rtp_packet;
44 } 57 }
45 58
46 // Creates a new RtpPacket with the RED header added to the packet. 59 // Creates a new RtpPacket with the RED header added to the packet.
47 test::RawRtpPacket* FrameGenerator::BuildMediaRedPacket( 60 RawRtpPacket* FrameGenerator::BuildMediaRedPacket(const RawRtpPacket* packet) {
48 const test::RawRtpPacket* packet) {
49 const size_t kHeaderLength = packet->header.header.headerLength; 61 const size_t kHeaderLength = packet->header.header.headerLength;
50 test::RawRtpPacket* red_packet = new test::RawRtpPacket; 62 RawRtpPacket* red_packet = new RawRtpPacket;
51 red_packet->header = packet->header; 63 red_packet->header = packet->header;
52 red_packet->length = packet->length + 1; // 1 byte RED header. 64 red_packet->length = packet->length + 1; // 1 byte RED header.
53 memset(red_packet->data, 0, red_packet->length); 65 memset(red_packet->data, 0, red_packet->length);
54 // Copy RTP header. 66 // Copy RTP header.
55 memcpy(red_packet->data, packet->data, kHeaderLength); 67 memcpy(red_packet->data, packet->data, kHeaderLength);
56 SetRedHeader(red_packet, red_packet->data[1] & 0x7f, kHeaderLength); 68 SetRedHeader(red_packet, red_packet->data[1] & 0x7f, kHeaderLength);
57 memcpy(red_packet->data + kHeaderLength + 1, packet->data + kHeaderLength, 69 memcpy(red_packet->data + kHeaderLength + 1, packet->data + kHeaderLength,
58 packet->length - kHeaderLength); 70 packet->length - kHeaderLength);
59 return red_packet; 71 return red_packet;
60 } 72 }
61 73
62 // Creates a new RtpPacket with FEC payload and red header. Does this by 74 // 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 75 // 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|. 76 // header. Finally replaces the payload with the content of |packet->data|.
65 test::RawRtpPacket* FrameGenerator::BuildFecRedPacket( 77 RawRtpPacket* FrameGenerator::BuildFecRedPacket(
66 const ForwardErrorCorrection::Packet* packet) { 78 const ForwardErrorCorrection::Packet* packet) {
67 // Create a fake media packet to get a correct header. 1 byte RED header. 79 // Create a fake media packet to get a correct header. 1 byte RED header.
68 ++num_packets_; 80 ++num_packets_;
69 test::RawRtpPacket* red_packet = NextPacket(0, packet->length + 1); 81 RawRtpPacket* red_packet = NextPacket(0, packet->length + 1);
70 red_packet->data[1] &= ~0x80; // Clear marker bit. 82 red_packet->data[1] &= ~0x80; // Clear marker bit.
71 const size_t kHeaderLength = red_packet->header.header.headerLength; 83 const size_t kHeaderLength = red_packet->header.header.headerLength;
72 SetRedHeader(red_packet, kFecPayloadType, kHeaderLength); 84 SetRedHeader(red_packet, kFecPayloadType, kHeaderLength);
73 memcpy(red_packet->data + kHeaderLength + 1, packet->data, packet->length); 85 memcpy(red_packet->data + kHeaderLength + 1, packet->data, packet->length);
74 red_packet->length = kHeaderLength + 1 + packet->length; 86 red_packet->length = kHeaderLength + 1 + packet->length;
75 return red_packet; 87 return red_packet;
76 } 88 }
77 89
78 void FrameGenerator::SetRedHeader(ForwardErrorCorrection::Packet* red_packet, 90 void FrameGenerator::SetRedHeader(ForwardErrorCorrection::Packet* red_packet,
79 uint8_t payload_type, 91 uint8_t payload_type,
80 size_t header_length) const { 92 size_t header_length) const {
81 // Replace pltype. 93 // Replace pltype.
82 red_packet->data[1] &= 0x80; // Reset. 94 red_packet->data[1] &= 0x80; // Reset.
83 red_packet->data[1] += kRedPayloadType; // Replace. 95 red_packet->data[1] += kRedPayloadType; // Replace.
84 96
85 // Add RED header, f-bit always 0. 97 // Add RED header, f-bit always 0.
86 red_packet->data[header_length] = payload_type; 98 red_packet->data[header_length] = payload_type;
87 } 99 }
88 100
89 void FrameGenerator::BuildRtpHeader(uint8_t* data, const RTPHeader* header) { 101 void FrameGenerator::BuildRtpHeader(uint8_t* data, const RTPHeader* header) {
90 data[0] = 0x80; // Version 2. 102 data[0] = 0x80; // Version 2.
91 data[1] = header->payloadType; 103 data[1] = header->payloadType;
92 data[1] |= (header->markerBit ? kRtpMarkerBitMask : 0); 104 data[1] |= (header->markerBit ? kRtpMarkerBitMask : 0);
93 ByteWriter<uint16_t>::WriteBigEndian(data + 2, header->sequenceNumber); 105 ByteWriter<uint16_t>::WriteBigEndian(data + 2, header->sequenceNumber);
94 ByteWriter<uint32_t>::WriteBigEndian(data + 4, header->timestamp); 106 ByteWriter<uint32_t>::WriteBigEndian(data + 4, header->timestamp);
95 ByteWriter<uint32_t>::WriteBigEndian(data + 8, header->ssrc); 107 ByteWriter<uint32_t>::WriteBigEndian(data + 8, header->ssrc);
96 } 108 }
97 109
110 void MediaPacketGenerator::ConstructMediaPacketsSeqNum(int num_media_packets,
111 uint16_t start_seq_num) {
112 RTC_DCHECK_GT(num_media_packets, 0);
113 uint16_t seq_num = start_seq_num;
114 int time_stamp = random_->Rand<int>();
115 uint32_t ssrc = random_->Rand<uint32_t>();
116
117 media_packets_.clear();
118
119 for (int i = 0; i < num_media_packets; ++i) {
120 std::unique_ptr<ForwardErrorCorrection::Packet> media_packet(
121 new ForwardErrorCorrection::Packet());
122 media_packet->length = random_->Rand(min_packet_size_, max_packet_size_);
123
124 // Generate random values for the first 2 bytes
125 media_packet->data[0] = random_->Rand<uint8_t>();
126 media_packet->data[1] = random_->Rand<uint8_t>();
127
128 // The first two bits are assumed to be 10 by the FEC encoder.
129 // In fact the FEC decoder will set the two first bits to 10 regardless of
130 // what they actually were. Set the first two bits to 10 so that a memcmp
131 // can be performed for the whole restored packet.
132 media_packet->data[0] |= 0x80;
133 media_packet->data[0] &= 0xbf;
134
135 // FEC is applied to a whole frame.
136 // A frame is signaled by multiple packets without the marker bit set
137 // followed by the last packet of the frame for which the marker bit is set.
138 // Only push one (fake) frame to the FEC.
139 media_packet->data[1] &= 0x7f;
140
141 webrtc::ByteWriter<uint16_t>::WriteBigEndian(&media_packet->data[2],
142 seq_num);
143 webrtc::ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[4],
144 time_stamp);
145 webrtc::ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[8], ssrc);
146
147 // Generate random values for payload.
148 for (size_t j = 12; j < media_packet->length; ++j) {
149 media_packet->data[j] = random_->Rand<uint8_t>();
150 }
151 seq_num++;
152 media_packets_.push_back(std::move(media_packet));
153 }
154 // Last packet, set marker bit.
155 ForwardErrorCorrection::Packet* media_packet = media_packets_.back().get();
156 RTC_DCHECK(media_packet);
157 media_packet->data[1] |= 0x80;
158
159 ssrc_ = ssrc;
160 fec_seq_num_ = seq_num;
161 }
162
163 void MediaPacketGenerator::ConstructMediaPackets(int num_media_packets) {
164 ConstructMediaPacketsSeqNum(num_media_packets, random_->Rand<int>());
165 }
166
167 ForwardErrorCorrection::PacketList* MediaPacketGenerator::GetMediaPackets() {
168 return &media_packets_;
169 }
170
171 uint32_t MediaPacketGenerator::GetSsrc() {
172 return ssrc_;
173 }
174
175 uint16_t MediaPacketGenerator::GetFecSeqNum() {
176 return fec_seq_num_;
177 }
178
179 } // namespace fec
180 } // namespace test
98 } // namespace webrtc 181 } // 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