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

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

Issue 1512493002: [rtp_rtcp] lint whitespace warning removed from most source/ files (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: rebase Created 5 years 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 <assert.h> //assert 13 #include <string.h>
14 #include <string.h> //memcpy
15 14
16 #include "webrtc/base/trace_event.h" 15 #include "webrtc/base/trace_event.h"
17 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" 16 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
18 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" 17 #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
19 #include "webrtc/system_wrappers/include/tick_util.h" 18 #include "webrtc/system_wrappers/include/tick_util.h"
20 19
21 namespace webrtc { 20 namespace webrtc {
22 21
23 static const int kDtmfFrequencyHz = 8000; 22 static const int kDtmfFrequencyHz = 8000;
24 23
(...skipping 16 matching lines...) Expand all
41 _dtmfTimestampLastSent(0), 40 _dtmfTimestampLastSent(0),
42 _REDPayloadType(-1), 41 _REDPayloadType(-1),
43 _inbandVADactive(false), 42 _inbandVADactive(false),
44 _cngNBPayloadType(-1), 43 _cngNBPayloadType(-1),
45 _cngWBPayloadType(-1), 44 _cngWBPayloadType(-1),
46 _cngSWBPayloadType(-1), 45 _cngSWBPayloadType(-1),
47 _cngFBPayloadType(-1), 46 _cngFBPayloadType(-1),
48 _lastPayloadType(-1), 47 _lastPayloadType(-1),
49 _audioLevel_dBov(0) {} 48 _audioLevel_dBov(0) {}
50 49
51 RTPSenderAudio::~RTPSenderAudio() { 50 RTPSenderAudio::~RTPSenderAudio() {}
52 }
53 51
54 int RTPSenderAudio::AudioFrequency() const { 52 int RTPSenderAudio::AudioFrequency() const {
55 return kDtmfFrequencyHz; 53 return kDtmfFrequencyHz;
56 } 54 }
57 55
58 // set audio packet size, used to determine when it's time to send a DTMF packet 56 // set audio packet size, used to determine when it's time to send a DTMF packet
59 // in silence (CNG) 57 // in silence (CNG)
60 int32_t 58 int32_t RTPSenderAudio::SetAudioPacketSize(uint16_t packetSizeSamples) {
61 RTPSenderAudio::SetAudioPacketSize(const uint16_t packetSizeSamples) 59 CriticalSectionScoped cs(_sendAudioCritsect.get());
62 {
63 CriticalSectionScoped cs(_sendAudioCritsect.get());
64 60
65 _packetSizeSamples = packetSizeSamples; 61 _packetSizeSamples = packetSizeSamples;
66 return 0; 62 return 0;
67 } 63 }
68 64
69 int32_t RTPSenderAudio::RegisterAudioPayload( 65 int32_t RTPSenderAudio::RegisterAudioPayload(
70 const char payloadName[RTP_PAYLOAD_NAME_SIZE], 66 const char payloadName[RTP_PAYLOAD_NAME_SIZE],
71 const int8_t payloadType, 67 const int8_t payloadType,
72 const uint32_t frequency, 68 const uint32_t frequency,
73 const uint8_t channels, 69 const uint8_t channels,
74 const uint32_t rate, 70 const uint32_t rate,
75 RtpUtility::Payload*& payload) { 71 RtpUtility::Payload*& payload) {
76 if (RtpUtility::StringCompare(payloadName, "cn", 2)) { 72 if (RtpUtility::StringCompare(payloadName, "cn", 2)) {
(...skipping 26 matching lines...) Expand all
103 payload = new RtpUtility::Payload; 99 payload = new RtpUtility::Payload;
104 payload->typeSpecific.Audio.frequency = frequency; 100 payload->typeSpecific.Audio.frequency = frequency;
105 payload->typeSpecific.Audio.channels = channels; 101 payload->typeSpecific.Audio.channels = channels;
106 payload->typeSpecific.Audio.rate = rate; 102 payload->typeSpecific.Audio.rate = rate;
107 payload->audio = true; 103 payload->audio = true;
108 payload->name[RTP_PAYLOAD_NAME_SIZE - 1] = '\0'; 104 payload->name[RTP_PAYLOAD_NAME_SIZE - 1] = '\0';
109 strncpy(payload->name, payloadName, RTP_PAYLOAD_NAME_SIZE - 1); 105 strncpy(payload->name, payloadName, RTP_PAYLOAD_NAME_SIZE - 1);
110 return 0; 106 return 0;
111 } 107 }
112 108
113 bool 109 bool RTPSenderAudio::MarkerBit(FrameType frameType, int8_t payload_type) {
114 RTPSenderAudio::MarkerBit(const FrameType frameType, 110 CriticalSectionScoped cs(_sendAudioCritsect.get());
115 const int8_t payload_type) 111 // for audio true for first packet in a speech burst
116 { 112 bool markerBit = false;
117 CriticalSectionScoped cs(_sendAudioCritsect.get()); 113 if (_lastPayloadType != payload_type) {
118 // for audio true for first packet in a speech burst 114 if (payload_type != -1 && (_cngNBPayloadType == payload_type ||
119 bool markerBit = false; 115 _cngWBPayloadType == payload_type ||
120 if (_lastPayloadType != payload_type) { 116 _cngSWBPayloadType == payload_type ||
121 if (payload_type != -1 && (_cngNBPayloadType == payload_type || 117 _cngFBPayloadType == payload_type)) {
122 _cngWBPayloadType == payload_type || 118 // Only set a marker bit when we change payload type to a non CNG
123 _cngSWBPayloadType == payload_type || 119 return false;
124 _cngFBPayloadType == payload_type)) { 120 }
125 // Only set a marker bit when we change payload type to a non CNG 121
122 // payload_type differ
123 if (_lastPayloadType == -1) {
124 if (frameType != kAudioFrameCN) {
125 // first packet and NOT CNG
126 return true;
127 } else {
128 // first packet and CNG
129 _inbandVADactive = true;
126 return false; 130 return false;
127 } 131 }
128
129 // payload_type differ
130 if (_lastPayloadType == -1) {
131 if (frameType != kAudioFrameCN) {
132 // first packet and NOT CNG
133 return true;
134 } else {
135 // first packet and CNG
136 _inbandVADactive = true;
137 return false;
138 }
139 }
140
141 // not first packet AND
142 // not CNG AND
143 // payload_type changed
144
145 // set a marker bit when we change payload type
146 markerBit = true;
147 } 132 }
148 133
149 // For G.723 G.729, AMR etc we can have inband VAD 134 // not first packet AND
150 if(frameType == kAudioFrameCN) 135 // not CNG AND
151 { 136 // payload_type changed
152 _inbandVADactive = true;
153 137
154 } else if(_inbandVADactive) 138 // set a marker bit when we change payload type
155 { 139 markerBit = true;
156 _inbandVADactive = false; 140 }
157 markerBit = true; 141
158 } 142 // For G.723 G.729, AMR etc we can have inband VAD
159 return markerBit; 143 if (frameType == kAudioFrameCN) {
144 _inbandVADactive = true;
145 } else if (_inbandVADactive) {
146 _inbandVADactive = false;
147 markerBit = true;
148 }
149 return markerBit;
160 } 150 }
161 151
162 int32_t RTPSenderAudio::SendAudio( 152 int32_t RTPSenderAudio::SendAudio(FrameType frameType,
163 const FrameType frameType, 153 int8_t payloadType,
164 const int8_t payloadType, 154 uint32_t captureTimeStamp,
165 const uint32_t captureTimeStamp, 155 const uint8_t* payloadData,
166 const uint8_t* payloadData, 156 size_t dataSize,
167 const size_t dataSize, 157 const RTPFragmentationHeader* fragmentation) {
168 const RTPFragmentationHeader* fragmentation) {
169 // TODO(pwestin) Breakup function in smaller functions. 158 // TODO(pwestin) Breakup function in smaller functions.
170 size_t payloadSize = dataSize; 159 size_t payloadSize = dataSize;
171 size_t maxPayloadLength = _rtpSender->MaxPayloadLength(); 160 size_t maxPayloadLength = _rtpSender->MaxPayloadLength();
172 bool dtmfToneStarted = false; 161 bool dtmfToneStarted = false;
173 uint16_t dtmfLengthMS = 0; 162 uint16_t dtmfLengthMS = 0;
174 uint8_t key = 0; 163 uint8_t key = 0;
175 int red_payload_type; 164 int red_payload_type;
176 uint8_t audio_level_dbov; 165 uint8_t audio_level_dbov;
177 int8_t dtmf_payload_type; 166 int8_t dtmf_payload_type;
178 uint16_t packet_size_samples; 167 uint16_t packet_size_samples;
179 { 168 {
180 CriticalSectionScoped cs(_sendAudioCritsect.get()); 169 CriticalSectionScoped cs(_sendAudioCritsect.get());
181 red_payload_type = _REDPayloadType; 170 red_payload_type = _REDPayloadType;
182 audio_level_dbov = _audioLevel_dBov; 171 audio_level_dbov = _audioLevel_dBov;
183 dtmf_payload_type = _dtmfPayloadType; 172 dtmf_payload_type = _dtmfPayloadType;
184 packet_size_samples = _packetSizeSamples; 173 packet_size_samples = _packetSizeSamples;
185 } 174 }
186 175
187 // Check if we have pending DTMFs to send 176 // Check if we have pending DTMFs to send
188 if (!_dtmfEventIsOn && PendingDTMF()) { 177 if (!_dtmfEventIsOn && PendingDTMF()) {
189 int64_t delaySinceLastDTMF = _clock->TimeInMilliseconds() - 178 int64_t delaySinceLastDTMF =
190 _dtmfTimeLastSent; 179 _clock->TimeInMilliseconds() - _dtmfTimeLastSent;
191 180
192 if (delaySinceLastDTMF > 100) { 181 if (delaySinceLastDTMF > 100) {
193 // New tone to play 182 // New tone to play
194 _dtmfTimestamp = captureTimeStamp; 183 _dtmfTimestamp = captureTimeStamp;
195 if (NextDTMF(&key, &dtmfLengthMS, &_dtmfLevel) >= 0) { 184 if (NextDTMF(&key, &dtmfLengthMS, &_dtmfLevel) >= 0) {
196 _dtmfEventFirstPacketSent = false; 185 _dtmfEventFirstPacketSent = false;
197 _dtmfKey = key; 186 _dtmfKey = key;
198 _dtmfLengthSamples = (kDtmfFrequencyHz / 1000) * dtmfLengthMS; 187 _dtmfLengthSamples = (kDtmfFrequencyHz / 1000) * dtmfLengthMS;
199 dtmfToneStarted = true; 188 dtmfToneStarted = true;
200 _dtmfEventIsOn = true; 189 _dtmfEventIsOn = true;
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 markerBit, captureTimeStamp, 277 markerBit, captureTimeStamp,
289 _clock->TimeInMilliseconds()); 278 _clock->TimeInMilliseconds());
290 } 279 }
291 if (rtpHeaderLength <= 0) { 280 if (rtpHeaderLength <= 0) {
292 return -1; 281 return -1;
293 } 282 }
294 if (maxPayloadLength < (rtpHeaderLength + payloadSize)) { 283 if (maxPayloadLength < (rtpHeaderLength + payloadSize)) {
295 // Too large payload buffer. 284 // Too large payload buffer.
296 return -1; 285 return -1;
297 } 286 }
298 if (red_payload_type >= 0 && // Have we configured RED? 287 if (red_payload_type >= 0 && // Have we configured RED?
299 fragmentation && fragmentation->fragmentationVectorSize > 1 && 288 fragmentation && fragmentation->fragmentationVectorSize > 1 &&
300 !markerBit) { 289 !markerBit) {
301 if (timestampOffset <= 0x3fff) { 290 if (timestampOffset <= 0x3fff) {
302 if (fragmentation->fragmentationVectorSize != 2) { 291 if (fragmentation->fragmentationVectorSize != 2) {
303 // we only support 2 codecs when using RED 292 // we only support 2 codecs when using RED
304 return -1; 293 return -1;
305 } 294 }
306 // only 0x80 if we have multiple blocks 295 // only 0x80 if we have multiple blocks
307 dataBuffer[rtpHeaderLength++] = 296 dataBuffer[rtpHeaderLength++] =
308 0x80 + fragmentation->fragmentationPlType[1]; 297 0x80 + fragmentation->fragmentationPlType[1];
309 size_t blockLength = fragmentation->fragmentationLength[1]; 298 size_t blockLength = fragmentation->fragmentationLength[1];
310 299
311 // sanity blockLength 300 // sanity blockLength
312 if (blockLength > 0x3ff) { // block length 10 bits 1023 bytes 301 if (blockLength > 0x3ff) { // block length 10 bits 1023 bytes
313 return -1; 302 return -1;
314 } 303 }
315 uint32_t REDheader = (timestampOffset << 10) + blockLength; 304 uint32_t REDheader = (timestampOffset << 10) + blockLength;
316 ByteWriter<uint32_t>::WriteBigEndian(dataBuffer + rtpHeaderLength, 305 ByteWriter<uint32_t>::WriteBigEndian(dataBuffer + rtpHeaderLength,
317 REDheader); 306 REDheader);
318 rtpHeaderLength += 3; 307 rtpHeaderLength += 3;
319 308
320 dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0]; 309 dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0];
321 // copy the RED data 310 // copy the RED data
322 memcpy(dataBuffer + rtpHeaderLength, 311 memcpy(dataBuffer + rtpHeaderLength,
323 payloadData + fragmentation->fragmentationOffset[1], 312 payloadData + fragmentation->fragmentationOffset[1],
324 fragmentation->fragmentationLength[1]); 313 fragmentation->fragmentationLength[1]);
325 314
326 // copy the normal data 315 // copy the normal data
327 memcpy(dataBuffer + rtpHeaderLength + 316 memcpy(
328 fragmentation->fragmentationLength[1], 317 dataBuffer + rtpHeaderLength + fragmentation->fragmentationLength[1],
329 payloadData + fragmentation->fragmentationOffset[0], 318 payloadData + fragmentation->fragmentationOffset[0],
330 fragmentation->fragmentationLength[0]); 319 fragmentation->fragmentationLength[0]);
331 320
332 payloadSize = fragmentation->fragmentationLength[0] + 321 payloadSize = fragmentation->fragmentationLength[0] +
333 fragmentation->fragmentationLength[1]; 322 fragmentation->fragmentationLength[1];
334 } else { 323 } else {
335 // silence for too long send only new data 324 // silence for too long send only new data
336 dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0]; 325 dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0];
337 memcpy(dataBuffer + rtpHeaderLength, 326 memcpy(dataBuffer + rtpHeaderLength,
338 payloadData + fragmentation->fragmentationOffset[0], 327 payloadData + fragmentation->fragmentationOffset[0],
339 fragmentation->fragmentationLength[0]); 328 fragmentation->fragmentationLength[0]);
340 329
341 payloadSize = fragmentation->fragmentationLength[0]; 330 payloadSize = fragmentation->fragmentationLength[0];
342 } 331 }
332 } else {
333 if (fragmentation && fragmentation->fragmentationVectorSize > 0) {
334 // use the fragment info if we have one
335 dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0];
336 memcpy(dataBuffer + rtpHeaderLength,
337 payloadData + fragmentation->fragmentationOffset[0],
338 fragmentation->fragmentationLength[0]);
339
340 payloadSize = fragmentation->fragmentationLength[0];
343 } else { 341 } else {
344 if (fragmentation && fragmentation->fragmentationVectorSize > 0) { 342 memcpy(dataBuffer + rtpHeaderLength, payloadData, payloadSize);
345 // use the fragment info if we have one
346 dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0];
347 memcpy(dataBuffer + rtpHeaderLength,
348 payloadData + fragmentation->fragmentationOffset[0],
349 fragmentation->fragmentationLength[0]);
350
351 payloadSize = fragmentation->fragmentationLength[0];
352 } else {
353 memcpy(dataBuffer + rtpHeaderLength, payloadData, payloadSize);
354 }
355 } 343 }
356 {
357 CriticalSectionScoped cs(_sendAudioCritsect.get());
358 _lastPayloadType = payloadType;
359 }
360 // Update audio level extension, if included.
361 size_t packetSize = payloadSize + rtpHeaderLength;
362 RtpUtility::RtpHeaderParser rtp_parser(dataBuffer, packetSize);
363 RTPHeader rtp_header;
364 rtp_parser.Parse(rtp_header);
365 _rtpSender->UpdateAudioLevel(dataBuffer, packetSize, rtp_header,
366 (frameType == kAudioFrameSpeech),
367 audio_level_dbov);
368 TRACE_EVENT_ASYNC_END2("webrtc", "Audio", captureTimeStamp, "timestamp",
369 _rtpSender->Timestamp(), "seqnum",
370 _rtpSender->SequenceNumber());
371 return _rtpSender->SendToNetwork(dataBuffer, payloadSize, rtpHeaderLength,
372 TickTime::MillisecondTimestamp(),
373 kAllowRetransmission,
374 RtpPacketSender::kHighPriority);
375 } 344 }
376 345 {
377 // Audio level magnitude and voice activity flag are set for each RTP packet
378 int32_t
379 RTPSenderAudio::SetAudioLevel(const uint8_t level_dBov)
380 {
381 if (level_dBov > 127)
382 {
383 return -1;
384 }
385 CriticalSectionScoped cs(_sendAudioCritsect.get()); 346 CriticalSectionScoped cs(_sendAudioCritsect.get());
386 _audioLevel_dBov = level_dBov; 347 _lastPayloadType = payloadType;
387 return 0; 348 }
349 // Update audio level extension, if included.
350 size_t packetSize = payloadSize + rtpHeaderLength;
351 RtpUtility::RtpHeaderParser rtp_parser(dataBuffer, packetSize);
352 RTPHeader rtp_header;
353 rtp_parser.Parse(rtp_header);
354 _rtpSender->UpdateAudioLevel(dataBuffer, packetSize, rtp_header,
355 (frameType == kAudioFrameSpeech),
356 audio_level_dbov);
357 TRACE_EVENT_ASYNC_END2("webrtc", "Audio", captureTimeStamp, "timestamp",
358 _rtpSender->Timestamp(), "seqnum",
359 _rtpSender->SequenceNumber());
360 return _rtpSender->SendToNetwork(dataBuffer, payloadSize, rtpHeaderLength,
361 TickTime::MillisecondTimestamp(),
362 kAllowRetransmission,
363 RtpPacketSender::kHighPriority);
388 } 364 }
389 365
390 // Set payload type for Redundant Audio Data RFC 2198 366 // Audio level magnitude and voice activity flag are set for each RTP packet
391 int32_t 367 int32_t RTPSenderAudio::SetAudioLevel(uint8_t level_dBov) {
392 RTPSenderAudio::SetRED(const int8_t payloadType) 368 if (level_dBov > 127) {
393 { 369 return -1;
394 if(payloadType < -1 ) 370 }
395 { 371 CriticalSectionScoped cs(_sendAudioCritsect.get());
396 return -1; 372 _audioLevel_dBov = level_dBov;
397 } 373 return 0;
398 CriticalSectionScoped cs(_sendAudioCritsect.get());
399 _REDPayloadType = payloadType;
400 return 0;
401 } 374 }
402 375
403 // Get payload type for Redundant Audio Data RFC 2198 376 // Set payload type for Redundant Audio Data RFC 2198
404 int32_t 377 int32_t RTPSenderAudio::SetRED(int8_t payloadType) {
405 RTPSenderAudio::RED(int8_t& payloadType) const 378 if (payloadType < -1) {
406 { 379 return -1;
407 CriticalSectionScoped cs(_sendAudioCritsect.get()); 380 }
408 if(_REDPayloadType == -1) 381 CriticalSectionScoped cs(_sendAudioCritsect.get());
409 { 382 _REDPayloadType = payloadType;
410 // not configured 383 return 0;
411 return -1; 384 }
412 } 385
413 payloadType = _REDPayloadType; 386 // Get payload type for Redundant Audio Data RFC 2198
414 return 0; 387 int32_t RTPSenderAudio::RED(int8_t& payloadType) const {
388 CriticalSectionScoped cs(_sendAudioCritsect.get());
389 if (_REDPayloadType == -1) {
390 // not configured
391 return -1;
392 }
393 payloadType = _REDPayloadType;
394 return 0;
415 } 395 }
416 396
417 // Send a TelephoneEvent tone using RFC 2833 (4733) 397 // Send a TelephoneEvent tone using RFC 2833 (4733)
418 int32_t RTPSenderAudio::SendTelephoneEvent(const uint8_t key, 398 int32_t RTPSenderAudio::SendTelephoneEvent(uint8_t key,
419 const uint16_t time_ms, 399 uint16_t time_ms,
420 const uint8_t level) { 400 uint8_t level) {
421 { 401 {
422 CriticalSectionScoped lock(_sendAudioCritsect.get()); 402 CriticalSectionScoped lock(_sendAudioCritsect.get());
423 if (_dtmfPayloadType < 0) { 403 if (_dtmfPayloadType < 0) {
424 // TelephoneEvent payloadtype not configured 404 // TelephoneEvent payloadtype not configured
425 return -1; 405 return -1;
426 } 406 }
427 } 407 }
428 return AddDTMF(key, time_ms, level); 408 return AddDTMF(key, time_ms, level);
429 } 409 }
430 410
431 int32_t 411 int32_t RTPSenderAudio::SendTelephoneEventPacket(bool ended,
432 RTPSenderAudio::SendTelephoneEventPacket(bool ended, 412 int8_t dtmf_payload_type,
433 int8_t dtmf_payload_type, 413 uint32_t dtmfTimeStamp,
434 uint32_t dtmfTimeStamp, 414 uint16_t duration,
435 uint16_t duration, 415 bool markerBit) {
436 bool markerBit) 416 uint8_t dtmfbuffer[IP_PACKET_SIZE];
437 { 417 uint8_t sendCount = 1;
438 uint8_t dtmfbuffer[IP_PACKET_SIZE]; 418 int32_t retVal = 0;
439 uint8_t sendCount = 1;
440 int32_t retVal = 0;
441 419
442 if(ended) 420 if (ended) {
443 { 421 // resend last packet in an event 3 times
444 // resend last packet in an event 3 times 422 sendCount = 3;
445 sendCount = 3; 423 }
446 } 424 do {
447 do 425 // Send DTMF data
448 { 426 _rtpSender->BuildRTPheader(dtmfbuffer, dtmf_payload_type, markerBit,
449 //Send DTMF data 427 dtmfTimeStamp, _clock->TimeInMilliseconds());
450 _rtpSender->BuildRTPheader(dtmfbuffer, dtmf_payload_type, markerBit,
451 dtmfTimeStamp, _clock->TimeInMilliseconds());
452 428
453 // reset CSRC and X bit 429 // reset CSRC and X bit
454 dtmfbuffer[0] &= 0xe0; 430 dtmfbuffer[0] &= 0xe0;
455 431
456 //Create DTMF data 432 // Create DTMF data
457 /* From RFC 2833: 433 /* From RFC 2833:
458 434
459 0 1 2 3 435 0 1 2 3
460 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 436 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
461 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 437 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
462 | event |E|R| volume | duration | 438 | event |E|R| volume | duration |
463 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 439 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
464 */ 440 */
465 // R bit always cleared 441 // R bit always cleared
466 uint8_t R = 0x00; 442 uint8_t R = 0x00;
467 uint8_t volume = _dtmfLevel; 443 uint8_t volume = _dtmfLevel;
468 444
469 // First packet un-ended 445 // First packet un-ended
470 uint8_t E = ended ? 0x80 : 0x00; 446 uint8_t E = ended ? 0x80 : 0x00;
471 447
472 // First byte is Event number, equals key number 448 // First byte is Event number, equals key number
473 dtmfbuffer[12] = _dtmfKey; 449 dtmfbuffer[12] = _dtmfKey;
474 dtmfbuffer[13] = E|R|volume; 450 dtmfbuffer[13] = E | R | volume;
475 ByteWriter<uint16_t>::WriteBigEndian(dtmfbuffer + 14, duration); 451 ByteWriter<uint16_t>::WriteBigEndian(dtmfbuffer + 14, duration);
476 452
477 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), 453 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
478 "Audio::SendTelephoneEvent", "timestamp", 454 "Audio::SendTelephoneEvent", "timestamp",
479 dtmfTimeStamp, "seqnum", 455 dtmfTimeStamp, "seqnum", _rtpSender->SequenceNumber());
480 _rtpSender->SequenceNumber()); 456 retVal = _rtpSender->SendToNetwork(
481 retVal = _rtpSender->SendToNetwork( 457 dtmfbuffer, 4, 12, TickTime::MillisecondTimestamp(),
482 dtmfbuffer, 4, 12, TickTime::MillisecondTimestamp(), 458 kAllowRetransmission, RtpPacketSender::kHighPriority);
483 kAllowRetransmission, RtpPacketSender::kHighPriority); 459 sendCount--;
484 sendCount--; 460 } while (sendCount > 0 && retVal == 0);
485 461
486 }while (sendCount > 0 && retVal == 0); 462 return retVal;
487
488 return retVal;
489 } 463 }
490 } // namespace webrtc 464 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/rtp_rtcp/source/rtp_sender_audio.h ('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