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

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

Issue 1739273002: [Draft] RtpPacket sketched. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: rebase to use landed version of rtp::Packet Created 4 years, 8 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/rtp_sender_audio.h" 11 #include "webrtc/modules/rtp_rtcp/source/rtp_sender_audio.h"
12 12
13 #include <string.h> 13 #include <string.h>
14 14
15 #include "webrtc/base/logging.h" 15 #include "webrtc/base/logging.h"
16 #include "webrtc/base/trace_event.h" 16 #include "webrtc/base/trace_event.h"
17 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" 17 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
18 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" 18 #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
19 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_to_send.h"
19 #include "webrtc/system_wrappers/include/tick_util.h" 20 #include "webrtc/system_wrappers/include/tick_util.h"
20 21
21 namespace webrtc { 22 namespace webrtc {
22 23
23 static const int kDtmfFrequencyHz = 8000; 24 static const int kDtmfFrequencyHz = 8000;
24 25
25 RTPSenderAudio::RTPSenderAudio(Clock* clock, RTPSender* rtpSender) 26 RTPSenderAudio::RTPSenderAudio(Clock* clock, RTPSender* rtpSender)
26 : _clock(clock), 27 : _clock(clock),
27 _rtpSender(rtpSender), 28 _rtpSender(rtpSender),
28 _packetSizeSamples(160), 29 _packetSizeSamples(160),
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 return markerBit; 147 return markerBit;
147 } 148 }
148 149
149 int32_t RTPSenderAudio::SendAudio(FrameType frameType, 150 int32_t RTPSenderAudio::SendAudio(FrameType frameType,
150 int8_t payloadType, 151 int8_t payloadType,
151 uint32_t captureTimeStamp, 152 uint32_t captureTimeStamp,
152 const uint8_t* payloadData, 153 const uint8_t* payloadData,
153 size_t dataSize, 154 size_t dataSize,
154 const RTPFragmentationHeader* fragmentation) { 155 const RTPFragmentationHeader* fragmentation) {
155 // TODO(pwestin) Breakup function in smaller functions. 156 // TODO(pwestin) Breakup function in smaller functions.
156 size_t payloadSize = dataSize; 157 size_t payload_size = dataSize;
157 size_t maxPayloadLength = _rtpSender->MaxPayloadLength(); 158 size_t maxPayloadLength = _rtpSender->MaxPayloadLength();
158 uint16_t dtmfLengthMS = 0; 159 uint16_t dtmfLengthMS = 0;
159 uint8_t key = 0; 160 uint8_t key = 0;
160 int red_payload_type; 161 int red_payload_type;
161 uint8_t audio_level_dbov; 162 uint8_t audio_level_dbov;
162 int8_t dtmf_payload_type; 163 int8_t dtmf_payload_type;
163 uint16_t packet_size_samples; 164 uint16_t packet_size_samples;
164 { 165 {
165 rtc::CritScope cs(&_sendAudioCritsect); 166 rtc::CritScope cs(&_sendAudioCritsect);
166 red_payload_type = _REDPayloadType; 167 red_payload_type = _REDPayloadType;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 static_cast<uint16_t>(dtmfDurationSamples), 233 static_cast<uint16_t>(dtmfDurationSamples),
233 !_dtmfEventFirstPacketSent) != 0) { 234 !_dtmfEventFirstPacketSent) != 0) {
234 return -1; 235 return -1;
235 } 236 }
236 _dtmfEventFirstPacketSent = true; 237 _dtmfEventFirstPacketSent = true;
237 return 0; 238 return 0;
238 } 239 }
239 } 240 }
240 return 0; 241 return 0;
241 } 242 }
242 if (payloadSize == 0 || payloadData == NULL) { 243 if (payload_size == 0 || payloadData == NULL) {
243 if (frameType == kEmptyFrame) { 244 if (frameType == kEmptyFrame) {
244 // we don't send empty audio RTP packets 245 // we don't send empty audio RTP packets
245 // no error since we use it to drive DTMF when we use VAD 246 // no error since we use it to drive DTMF when we use VAD
246 return 0; 247 return 0;
247 } 248 }
248 return -1; 249 return -1;
249 } 250 }
250 uint8_t dataBuffer[IP_PACKET_SIZE]; 251 std::unique_ptr<RtpPacketToSend> packet = _rtpSender->CreatePacket();
251 bool markerBit = MarkerBit(frameType, payloadType); 252 bool markerBit = MarkerBit(frameType, payloadType);
252 253
253 int32_t rtpHeaderLength = 0;
254 uint16_t timestampOffset = 0; 254 uint16_t timestampOffset = 0;
255 255
256 if (red_payload_type >= 0 && fragmentation && !markerBit && 256 if (red_payload_type >= 0 && fragmentation && !markerBit &&
257 fragmentation->fragmentationVectorSize > 1) { 257 fragmentation->fragmentationVectorSize > 1) {
258 // have we configured RED? use its payload type 258 // have we configured RED? use its payload type
259 // we need to get the current timestamp to calc the diff 259 // we need to get the current timestamp to calc the diff
260 uint32_t oldTimeStamp = _rtpSender->Timestamp(); 260 uint32_t oldTimeStamp = _rtpSender->Timestamp();
261 rtpHeaderLength = _rtpSender->BuildRTPheader(dataBuffer, red_payload_type, 261 _rtpSender->BuildRtpHeader(packet.get(), captureTimeStamp, true);
262 markerBit, captureTimeStamp, 262 timestampOffset = uint16_t(_rtpSender->Timestamp() - oldTimeStamp);
263 _clock->TimeInMilliseconds()); 263 packet->SetPayloadType(red_payload_type);
264 } else {
265 _rtpSender->BuildRtpHeader(packet.get(), captureTimeStamp, true);
266 packet->SetPayloadType(payloadType);
267 }
268 packet->SetMarker(markerBit);
269 // Update audio level extension, if included.
270 packet->SetExtension<AudioLevel>(frameType == kAudioFrameSpeech,
271 audio_level_dbov);
264 272
265 timestampOffset = uint16_t(_rtpSender->Timestamp() - oldTimeStamp); 273 if (maxPayloadLength < (packet->headers_size() + payload_size)) {
266 } else {
267 rtpHeaderLength = _rtpSender->BuildRTPheader(dataBuffer, payloadType,
268 markerBit, captureTimeStamp,
269 _clock->TimeInMilliseconds());
270 }
271 if (rtpHeaderLength <= 0) {
272 return -1;
273 }
274 if (maxPayloadLength < (rtpHeaderLength + payloadSize)) {
275 // Too large payload buffer. 274 // Too large payload buffer.
276 return -1; 275 return -1;
277 } 276 }
277 size_t red_header_size = 0;
278 if (red_payload_type >= 0 && // Have we configured RED? 278 if (red_payload_type >= 0 && // Have we configured RED?
279 fragmentation && fragmentation->fragmentationVectorSize > 1 && 279 fragmentation && fragmentation->fragmentationVectorSize > 1 &&
280 !markerBit) { 280 !markerBit) {
281 if (timestampOffset <= 0x3fff) { 281 if (timestampOffset <= 0x3fff) {
282 if (fragmentation->fragmentationVectorSize != 2) { 282 if (fragmentation->fragmentationVectorSize != 2) {
283 // we only support 2 codecs when using RED 283 // we only support 2 codecs when using RED
284 return -1; 284 return -1;
285 } 285 }
286 red_header_size = 5;
287 payload_size = fragmentation->fragmentationLength[0] +
288 fragmentation->fragmentationLength[1];
289
290 uint8_t* payload =
291 packet->AllocatePayload(red_header_size + payload_size);
286 // only 0x80 if we have multiple blocks 292 // only 0x80 if we have multiple blocks
287 dataBuffer[rtpHeaderLength++] = 293 payload[0] = 0x80 + fragmentation->fragmentationPlType[1];
288 0x80 + fragmentation->fragmentationPlType[1];
289 size_t blockLength = fragmentation->fragmentationLength[1]; 294 size_t blockLength = fragmentation->fragmentationLength[1];
290 295
291 // sanity blockLength 296 // sanity blockLength
292 if (blockLength > 0x3ff) { // block length 10 bits 1023 bytes 297 if (blockLength > 0x3ff) { // block length 10 bits 1023 bytes
293 return -1; 298 return -1;
294 } 299 }
295 uint32_t REDheader = (timestampOffset << 10) + blockLength; 300 uint32_t REDheader = (timestampOffset << 10) + blockLength;
296 ByteWriter<uint32_t>::WriteBigEndian(dataBuffer + rtpHeaderLength, 301 ByteWriter<uint32_t, 3>::WriteBigEndian(payload + 1, REDheader);
297 REDheader);
298 rtpHeaderLength += 3;
299 302
300 dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0]; 303 payload[4] = fragmentation->fragmentationPlType[0];
301 // copy the RED data 304 // copy the RED data
302 memcpy(dataBuffer + rtpHeaderLength, 305 memcpy(payload + red_header_size,
303 payloadData + fragmentation->fragmentationOffset[1], 306 payloadData + fragmentation->fragmentationOffset[1],
304 fragmentation->fragmentationLength[1]); 307 fragmentation->fragmentationLength[1]);
305 308
306 // copy the normal data 309 // copy the normal data
307 memcpy( 310 memcpy(payload + red_header_size + fragmentation->fragmentationLength[1],
308 dataBuffer + rtpHeaderLength + fragmentation->fragmentationLength[1],
309 payloadData + fragmentation->fragmentationOffset[0],
310 fragmentation->fragmentationLength[0]);
311
312 payloadSize = fragmentation->fragmentationLength[0] +
313 fragmentation->fragmentationLength[1];
314 } else {
315 // silence for too long send only new data
316 dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0];
317 memcpy(dataBuffer + rtpHeaderLength,
318 payloadData + fragmentation->fragmentationOffset[0], 311 payloadData + fragmentation->fragmentationOffset[0],
319 fragmentation->fragmentationLength[0]); 312 fragmentation->fragmentationLength[0]);
320 313 } else {
321 payloadSize = fragmentation->fragmentationLength[0]; 314 red_header_size = 1;
315 payload_size = fragmentation->fragmentationLength[0];
316 uint8_t* payload =
317 packet->AllocatePayload(red_header_size + payload_size);
318 // silence for too long send only new data
319 payload[0] = fragmentation->fragmentationPlType[0];
320 memcpy(payload + red_header_size,
321 payloadData + fragmentation->fragmentationOffset[0],
322 fragmentation->fragmentationLength[0]);
322 } 323 }
323 } else { 324 } else {
324 if (fragmentation && fragmentation->fragmentationVectorSize > 0) { 325 if (fragmentation && fragmentation->fragmentationVectorSize > 0) {
325 // use the fragment info if we have one 326 // use the fragment info if we have one
326 dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0]; 327 red_header_size = 1;
327 memcpy(dataBuffer + rtpHeaderLength, 328 payload_size = fragmentation->fragmentationLength[0];
329 uint8_t* payload =
330 packet->AllocatePayload(red_header_size + payload_size);
331 payload[0] = fragmentation->fragmentationPlType[0];
332 memcpy(payload + red_header_size,
328 payloadData + fragmentation->fragmentationOffset[0], 333 payloadData + fragmentation->fragmentationOffset[0],
329 fragmentation->fragmentationLength[0]); 334 fragmentation->fragmentationLength[0]);
330
331 payloadSize = fragmentation->fragmentationLength[0];
332 } else { 335 } else {
333 memcpy(dataBuffer + rtpHeaderLength, payloadData, payloadSize); 336 uint8_t* payload = packet->AllocatePayload(payload_size);
337 memcpy(payload, payloadData, payload_size);
334 } 338 }
335 } 339 }
336 340
337 { 341 {
338 rtc::CritScope cs(&_sendAudioCritsect); 342 rtc::CritScope cs(&_sendAudioCritsect);
339 _lastPayloadType = payloadType; 343 _lastPayloadType = payloadType;
340 } 344 }
341 // Update audio level extension, if included.
342 size_t packetSize = payloadSize + rtpHeaderLength;
343 RtpUtility::RtpHeaderParser rtp_parser(dataBuffer, packetSize);
344 RTPHeader rtp_header;
345 rtp_parser.Parse(&rtp_header);
346 _rtpSender->UpdateAudioLevel(dataBuffer, packetSize, rtp_header,
347 (frameType == kAudioFrameSpeech),
348 audio_level_dbov);
349 TRACE_EVENT_ASYNC_END2("webrtc", "Audio", captureTimeStamp, "timestamp", 345 TRACE_EVENT_ASYNC_END2("webrtc", "Audio", captureTimeStamp, "timestamp",
350 _rtpSender->Timestamp(), "seqnum", 346 packet->Timestamp(), "seqnum",
351 _rtpSender->SequenceNumber()); 347 packet->SequenceNumber());
352 int32_t send_result = _rtpSender->SendToNetwork( 348 return _rtpSender->SendToNetwork(
353 dataBuffer, payloadSize, rtpHeaderLength, 349 std::move(packet), payload_size, TickTime::MillisecondTimestamp(),
354 TickTime::MillisecondTimestamp(), kAllowRetransmission, 350 kAllowRetransmission, RtpPacketSender::kHighPriority);
355 RtpPacketSender::kHighPriority);
356 if (first_packet_sent_()) {
357 LOG(LS_INFO) << "First audio RTP packet sent to pacer";
358 }
359 return send_result;
360 } 351 }
361 352
362 // Audio level magnitude and voice activity flag are set for each RTP packet 353 // Audio level magnitude and voice activity flag are set for each RTP packet
363 int32_t RTPSenderAudio::SetAudioLevel(uint8_t level_dBov) { 354 int32_t RTPSenderAudio::SetAudioLevel(uint8_t level_dBov) {
364 if (level_dBov > 127) { 355 if (level_dBov > 127) {
365 return -1; 356 return -1;
366 } 357 }
367 rtc::CritScope cs(&_sendAudioCritsect); 358 rtc::CritScope cs(&_sendAudioCritsect);
368 _audioLevel_dBov = level_dBov; 359 _audioLevel_dBov = level_dBov;
369 return 0; 360 return 0;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 } 393 }
403 } 394 }
404 return AddDTMF(key, time_ms, level); 395 return AddDTMF(key, time_ms, level);
405 } 396 }
406 397
407 int32_t RTPSenderAudio::SendTelephoneEventPacket(bool ended, 398 int32_t RTPSenderAudio::SendTelephoneEventPacket(bool ended,
408 int8_t dtmf_payload_type, 399 int8_t dtmf_payload_type,
409 uint32_t dtmfTimeStamp, 400 uint32_t dtmfTimeStamp,
410 uint16_t duration, 401 uint16_t duration,
411 bool markerBit) { 402 bool markerBit) {
412 uint8_t dtmfbuffer[IP_PACKET_SIZE];
413 uint8_t sendCount = 1; 403 uint8_t sendCount = 1;
414 int32_t retVal = 0; 404 int32_t retVal = 0;
415 405
416 if (ended) { 406 if (ended) {
417 // resend last packet in an event 3 times 407 // resend last packet in an event 3 times
418 sendCount = 3; 408 sendCount = 3;
419 } 409 }
420 do { 410 do {
411 std::unique_ptr<RtpPacketToSend> packet = _rtpSender->CreatePacket();
421 // Send DTMF data 412 // Send DTMF data
422 _rtpSender->BuildRTPheader(dtmfbuffer, dtmf_payload_type, markerBit, 413 _rtpSender->BuildRtpHeader(packet.get(), dtmfTimeStamp, false);
423 dtmfTimeStamp, _clock->TimeInMilliseconds()); 414 packet->SetMarker(markerBit);
424 415 packet->SetPayloadType(dtmf_payload_type);
425 // reset CSRC and X bit
426 dtmfbuffer[0] &= 0xe0;
427
428 // Create DTMF data 416 // Create DTMF data
429 /* From RFC 2833: 417 /* From RFC 2833:
430 418
431 0 1 2 3 419 0 1 2 3
432 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 420 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
433 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 421 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
434 | event |E|R| volume | duration | 422 | event |E|R| volume | duration |
435 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 423 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
436 */ 424 */
437 // R bit always cleared 425 // R bit always cleared
438 uint8_t R = 0x00; 426 uint8_t R = 0x00;
439 uint8_t volume = _dtmfLevel; 427 uint8_t volume = _dtmfLevel;
440 428
441 // First packet un-ended 429 // First packet un-ended
442 uint8_t E = ended ? 0x80 : 0x00; 430 uint8_t E = ended ? 0x80 : 0x00;
431 uint8_t* dtmfbuffer = packet->AllocatePayload(4);
443 432
444 // First byte is Event number, equals key number 433 // First byte is Event number, equals key number
445 dtmfbuffer[12] = _dtmfKey; 434 dtmfbuffer[0] = _dtmfKey;
446 dtmfbuffer[13] = E | R | volume; 435 dtmfbuffer[1] = E | R | volume;
447 ByteWriter<uint16_t>::WriteBigEndian(dtmfbuffer + 14, duration); 436 ByteWriter<uint16_t>::WriteBigEndian(dtmfbuffer + 2, duration);
448 437
449 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), 438 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
450 "Audio::SendTelephoneEvent", "timestamp", 439 "Audio::SendTelephoneEvent", "timestamp",
451 dtmfTimeStamp, "seqnum", _rtpSender->SequenceNumber()); 440 dtmfTimeStamp, "seqnum", _rtpSender->SequenceNumber());
452 retVal = _rtpSender->SendToNetwork( 441 retVal = _rtpSender->SendToNetwork(
453 dtmfbuffer, 4, 12, TickTime::MillisecondTimestamp(), 442 std::move(packet), 4, TickTime::MillisecondTimestamp(),
454 kAllowRetransmission, RtpPacketSender::kHighPriority); 443 kAllowRetransmission, RtpPacketSender::kHighPriority);
455 sendCount--; 444 sendCount--;
456 } while (sendCount > 0 && retVal == 0); 445 } while (sendCount > 0 && retVal == 0);
457 446
458 return retVal; 447 return retVal;
459 } 448 }
460 } // namespace webrtc 449 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/rtp_rtcp/source/rtp_sender.cc ('k') | webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698