OLD | NEW |
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 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 // Only push one (fake) frame to the FEC. | 57 // Only push one (fake) frame to the FEC. |
58 media_packet->data[1] &= 0x7f; | 58 media_packet->data[1] &= 0x7f; |
59 | 59 |
60 webrtc::ByteWriter<uint16_t>::WriteBigEndian(&media_packet->data[2], | 60 webrtc::ByteWriter<uint16_t>::WriteBigEndian(&media_packet->data[2], |
61 seq_num); | 61 seq_num); |
62 webrtc::ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[4], | 62 webrtc::ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[4], |
63 time_stamp); | 63 time_stamp); |
64 webrtc::ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[8], ssrc_); | 64 webrtc::ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[8], ssrc_); |
65 | 65 |
66 // Generate random values for payload. | 66 // Generate random values for payload. |
67 for (size_t j = 12; j < media_packet->length; ++j) { | 67 for (size_t j = 12; j < media_packet->length; ++j) |
68 media_packet->data[j] = random_->Rand<uint8_t>(); | 68 media_packet->data[j] = random_->Rand<uint8_t>(); |
69 } | |
70 seq_num++; | 69 seq_num++; |
71 media_packets.push_back(std::move(media_packet)); | 70 media_packets.push_back(std::move(media_packet)); |
72 } | 71 } |
73 // Last packet, set marker bit. | 72 // Last packet, set marker bit. |
74 ForwardErrorCorrection::Packet* media_packet = media_packets.back().get(); | 73 ForwardErrorCorrection::Packet* media_packet = media_packets.back().get(); |
75 RTC_DCHECK(media_packet); | 74 RTC_DCHECK(media_packet); |
76 media_packet->data[1] |= 0x80; | 75 media_packet->data[1] |= 0x80; |
77 | 76 |
78 fec_seq_num_ = seq_num; | 77 fec_seq_num_ = seq_num; |
79 | 78 |
80 return media_packets; | 79 return media_packets; |
81 } | 80 } |
82 | 81 |
83 ForwardErrorCorrection::PacketList MediaPacketGenerator::ConstructMediaPackets( | 82 ForwardErrorCorrection::PacketList MediaPacketGenerator::ConstructMediaPackets( |
84 int num_media_packets) { | 83 int num_media_packets) { |
85 return ConstructMediaPackets(num_media_packets, random_->Rand<uint16_t>()); | 84 return ConstructMediaPackets(num_media_packets, random_->Rand<uint16_t>()); |
86 } | 85 } |
87 | 86 |
88 uint16_t MediaPacketGenerator::GetFecSeqNum() { | 87 uint16_t MediaPacketGenerator::GetFecSeqNum() { |
89 return fec_seq_num_; | 88 return fec_seq_num_; |
90 } | 89 } |
91 | 90 |
92 UlpfecPacketGenerator::UlpfecPacketGenerator() | 91 AugmentedPacketGenerator::AugmentedPacketGenerator(uint32_t ssrc) |
93 : num_packets_(0), seq_num_(0), timestamp_(0) {} | 92 : num_packets_(0), ssrc_(ssrc), seq_num_(0), timestamp_(0) {} |
94 | 93 |
95 void UlpfecPacketGenerator::NewFrame(int num_packets) { | 94 void AugmentedPacketGenerator::NewFrame(size_t num_packets) { |
96 num_packets_ = num_packets; | 95 num_packets_ = num_packets; |
97 timestamp_ += 3000; | 96 timestamp_ += 3000; |
98 } | 97 } |
99 | 98 |
100 uint16_t UlpfecPacketGenerator::NextSeqNum() { | 99 uint16_t AugmentedPacketGenerator::NextPacketSeqNum() { |
101 return ++seq_num_; | 100 return ++seq_num_; |
102 } | 101 } |
103 | 102 |
104 RawRtpPacket* UlpfecPacketGenerator::NextPacket(int offset, size_t length) { | 103 std::unique_ptr<AugmentedPacket> AugmentedPacketGenerator::NextPacket( |
105 RawRtpPacket* rtp_packet = new RawRtpPacket; | 104 size_t offset, |
| 105 size_t length) { |
| 106 std::unique_ptr<AugmentedPacket> packet(new AugmentedPacket()); |
| 107 |
106 for (size_t i = 0; i < length; ++i) | 108 for (size_t i = 0; i < length; ++i) |
107 rtp_packet->data[i + kRtpHeaderSize] = offset + i; | 109 packet->data[i + kRtpHeaderSize] = offset + i; |
108 rtp_packet->length = length + kRtpHeaderSize; | 110 packet->length = length + kRtpHeaderSize; |
109 memset(&rtp_packet->header, 0, sizeof(WebRtcRTPHeader)); | 111 memset(&packet->header, 0, sizeof(WebRtcRTPHeader)); |
110 rtp_packet->header.frameType = kVideoFrameDelta; | 112 packet->header.frameType = kVideoFrameDelta; |
111 rtp_packet->header.header.headerLength = kRtpHeaderSize; | 113 packet->header.header.headerLength = kRtpHeaderSize; |
112 rtp_packet->header.header.markerBit = (num_packets_ == 1); | 114 packet->header.header.markerBit = (num_packets_ == 1); |
113 rtp_packet->header.header.sequenceNumber = seq_num_; | 115 packet->header.header.payloadType = kVp8PayloadType; |
114 rtp_packet->header.header.timestamp = timestamp_; | 116 packet->header.header.sequenceNumber = seq_num_; |
115 rtp_packet->header.header.payloadType = kVp8PayloadType; | 117 packet->header.header.timestamp = timestamp_; |
116 BuildRtpHeader(rtp_packet->data, &rtp_packet->header.header); | 118 packet->header.header.ssrc = ssrc_; |
| 119 WriteRtpHeader(packet->header.header, packet->data); |
117 ++seq_num_; | 120 ++seq_num_; |
118 --num_packets_; | 121 --num_packets_; |
119 return rtp_packet; | 122 |
| 123 return packet; |
120 } | 124 } |
121 | 125 |
122 // Creates a new RtpPacket with the RED header added to the packet. | 126 void AugmentedPacketGenerator::WriteRtpHeader(const RTPHeader& header, |
123 RawRtpPacket* UlpfecPacketGenerator::BuildMediaRedPacket( | 127 uint8_t* data) { |
124 const RawRtpPacket* packet) { | 128 data[0] = 0x80; // Version 2. |
125 const size_t kHeaderLength = packet->header.header.headerLength; | 129 data[1] = header.payloadType; |
126 RawRtpPacket* red_packet = new RawRtpPacket; | 130 data[1] |= (header.markerBit ? kRtpMarkerBitMask : 0); |
127 red_packet->header = packet->header; | 131 ByteWriter<uint16_t>::WriteBigEndian(data + 2, header.sequenceNumber); |
128 red_packet->length = packet->length + 1; // 1 byte RED header. | 132 ByteWriter<uint32_t>::WriteBigEndian(data + 4, header.timestamp); |
| 133 ByteWriter<uint32_t>::WriteBigEndian(data + 8, header.ssrc); |
| 134 } |
| 135 |
| 136 UlpfecPacketGenerator::UlpfecPacketGenerator(uint32_t ssrc) |
| 137 : AugmentedPacketGenerator(ssrc) {} |
| 138 |
| 139 std::unique_ptr<AugmentedPacket> UlpfecPacketGenerator::BuildMediaRedPacket( |
| 140 const AugmentedPacket& packet) { |
| 141 std::unique_ptr<AugmentedPacket> red_packet(new AugmentedPacket()); |
| 142 |
| 143 const size_t kHeaderLength = packet.header.header.headerLength; |
| 144 red_packet->header = packet.header; |
| 145 red_packet->length = packet.length + 1; // 1 byte RED header. |
129 memset(red_packet->data, 0, red_packet->length); | 146 memset(red_packet->data, 0, red_packet->length); |
130 // Copy RTP header. | 147 // Copy RTP header. |
131 memcpy(red_packet->data, packet->data, kHeaderLength); | 148 memcpy(red_packet->data, packet.data, kHeaderLength); |
132 SetRedHeader(red_packet, red_packet->data[1] & 0x7f, kHeaderLength); | 149 SetRedHeader(red_packet->data[1] & 0x7f, kHeaderLength, red_packet.get()); |
133 memcpy(red_packet->data + kHeaderLength + 1, packet->data + kHeaderLength, | 150 memcpy(red_packet->data + kHeaderLength + 1, packet.data + kHeaderLength, |
134 packet->length - kHeaderLength); | 151 packet.length - kHeaderLength); |
| 152 |
135 return red_packet; | 153 return red_packet; |
136 } | 154 } |
137 | 155 |
138 // Creates a new RtpPacket with FEC payload and RED header. Does this by | 156 std::unique_ptr<AugmentedPacket> UlpfecPacketGenerator::BuildUlpfecRedPacket( |
139 // creating a new fake media RtpPacket, clears the marker bit and adds a RED | 157 const ForwardErrorCorrection::Packet& packet) { |
140 // header. Finally replaces the payload with the content of |packet->data|. | |
141 RawRtpPacket* UlpfecPacketGenerator::BuildFecRedPacket( | |
142 const ForwardErrorCorrection::Packet* packet) { | |
143 // Create a fake media packet to get a correct header. 1 byte RED header. | 158 // Create a fake media packet to get a correct header. 1 byte RED header. |
144 ++num_packets_; | 159 ++num_packets_; |
145 RawRtpPacket* red_packet = NextPacket(0, packet->length + 1); | 160 std::unique_ptr<AugmentedPacket> red_packet = |
| 161 NextPacket(0, packet.length + 1); |
| 162 |
146 red_packet->data[1] &= ~0x80; // Clear marker bit. | 163 red_packet->data[1] &= ~0x80; // Clear marker bit. |
147 const size_t kHeaderLength = red_packet->header.header.headerLength; | 164 const size_t kHeaderLength = red_packet->header.header.headerLength; |
148 SetRedHeader(red_packet, kFecPayloadType, kHeaderLength); | 165 SetRedHeader(kFecPayloadType, kHeaderLength, red_packet.get()); |
149 memcpy(red_packet->data + kHeaderLength + 1, packet->data, packet->length); | 166 memcpy(red_packet->data + kHeaderLength + 1, packet.data, packet.length); |
150 red_packet->length = kHeaderLength + 1 + packet->length; | 167 red_packet->length = kHeaderLength + 1 + packet.length; |
| 168 |
151 return red_packet; | 169 return red_packet; |
152 } | 170 } |
153 | 171 |
154 void UlpfecPacketGenerator::SetRedHeader( | 172 void UlpfecPacketGenerator::SetRedHeader(uint8_t payload_type, |
155 ForwardErrorCorrection::Packet* red_packet, | 173 size_t header_length, |
156 uint8_t payload_type, | 174 AugmentedPacket* red_packet) { |
157 size_t header_length) const { | 175 // Replace payload type. |
158 // Replace pltype. | |
159 red_packet->data[1] &= 0x80; // Reset. | 176 red_packet->data[1] &= 0x80; // Reset. |
160 red_packet->data[1] += kRedPayloadType; // Replace. | 177 red_packet->data[1] += kRedPayloadType; // Replace. |
161 | 178 |
162 // Add RED header, f-bit always 0. | 179 // Add RED header, f-bit always 0. |
163 red_packet->data[header_length] = payload_type; | 180 red_packet->data[header_length] = payload_type; |
164 } | 181 } |
165 | 182 |
166 void UlpfecPacketGenerator::BuildRtpHeader(uint8_t* data, | |
167 const RTPHeader* header) { | |
168 data[0] = 0x80; // Version 2. | |
169 data[1] = header->payloadType; | |
170 data[1] |= (header->markerBit ? kRtpMarkerBitMask : 0); | |
171 ByteWriter<uint16_t>::WriteBigEndian(data + 2, header->sequenceNumber); | |
172 ByteWriter<uint32_t>::WriteBigEndian(data + 4, header->timestamp); | |
173 ByteWriter<uint32_t>::WriteBigEndian(data + 8, header->ssrc); | |
174 } | |
175 | |
176 } // namespace fec | 183 } // namespace fec |
177 } // namespace test | 184 } // namespace test |
178 } // namespace webrtc | 185 } // namespace webrtc |
OLD | NEW |