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

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

Issue 2217383002: Use RtpPacketToSend in RtpSenderVideo (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Rebase Created 4 years, 4 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/timeutils.h" 16 #include "webrtc/base/timeutils.h"
17 #include "webrtc/base/trace_event.h" 17 #include "webrtc/base/trace_event.h"
18 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" 18 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
19 #include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h"
20 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_to_send.h"
19 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" 21 #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
20 22
21 namespace webrtc { 23 namespace webrtc {
22 24
23 static const int kDtmfFrequencyHz = 8000; 25 static const int kDtmfFrequencyHz = 8000;
24 26
25 RTPSenderAudio::RTPSenderAudio(Clock* clock, RTPSender* rtp_sender) 27 RTPSenderAudio::RTPSenderAudio(Clock* clock, RTPSender* rtp_sender)
26 : clock_(clock), 28 : clock_(clock),
27 rtp_sender_(rtp_sender), 29 rtp_sender_(rtp_sender),
28 packet_size_samples_(160), 30 packet_size_samples_(160),
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 } 148 }
147 149
148 bool RTPSenderAudio::SendAudio(FrameType frame_type, 150 bool RTPSenderAudio::SendAudio(FrameType frame_type,
149 int8_t payload_type, 151 int8_t payload_type,
150 uint32_t capture_timestamp, 152 uint32_t capture_timestamp,
151 const uint8_t* payload_data, 153 const uint8_t* payload_data,
152 size_t data_size, 154 size_t data_size,
153 const RTPFragmentationHeader* fragmentation) { 155 const RTPFragmentationHeader* fragmentation) {
154 // TODO(pwestin) Breakup function in smaller functions. 156 // TODO(pwestin) Breakup function in smaller functions.
155 size_t payload_size = data_size; 157 size_t payload_size = data_size;
156 size_t max_payload_length = rtp_sender_->MaxPayloadLength();
157 uint16_t dtmf_length_ms = 0; 158 uint16_t dtmf_length_ms = 0;
158 uint8_t key = 0; 159 uint8_t key = 0;
159 int red_payload_type; 160 int red_payload_type;
160 uint8_t audio_level_dbov; 161 uint8_t audio_level_dbov;
161 int8_t dtmf_payload_type; 162 int8_t dtmf_payload_type;
162 uint16_t packet_size_samples; 163 uint16_t packet_size_samples;
163 { 164 {
164 rtc::CritScope cs(&send_audio_critsect_); 165 rtc::CritScope cs(&send_audio_critsect_);
165 red_payload_type = red_payload_type_; 166 red_payload_type = red_payload_type_;
166 audio_level_dbov = audio_level_dbov_; 167 audio_level_dbov = audio_level_dbov_;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 return true; 241 return true;
241 } 242 }
242 if (payload_size == 0 || payload_data == NULL) { 243 if (payload_size == 0 || payload_data == NULL) {
243 if (frame_type == kEmptyFrame) { 244 if (frame_type == 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 true; 247 return true;
247 } 248 }
248 return false; 249 return false;
249 } 250 }
250 uint8_t data_buffer[IP_PACKET_SIZE]; 251
252 std::unique_ptr<RtpPacketToSend> packet = rtp_sender_->AllocatePacket(false);
253 if (!packet)
254 return false;
251 bool marker_bit = MarkerBit(frame_type, payload_type); 255 bool marker_bit = MarkerBit(frame_type, payload_type);
256 packet->SetPayloadType(payload_type);
257 packet->SetMarker(marker_bit);
258 packet->SetTimestamp(capture_timestamp);
259 packet->set_capture_time_ms(clock_->TimeInMilliseconds());
260 // Update audio level extension, if included.
261 packet->SetExtension<AudioLevel>(frame_type == kAudioFrameSpeech,
262 audio_level_dbov);
252 263
253 int32_t rtpHeaderLength = 0; 264 if (fragmentation && fragmentation->fragmentationVectorSize > 0) {
254 uint16_t timestampOffset = 0; 265 // use the fragment info if we have one
255 266 uint8_t* payload =
256 if (red_payload_type >= 0 && fragmentation && !marker_bit && 267 packet->AllocatePayload(1 + fragmentation->fragmentationLength[0]);
257 fragmentation->fragmentationVectorSize > 1) { 268 if (!payload)
258 // have we configured RED? use its payload type 269 return false;
259 // we need to get the current timestamp to calc the diff 270 payload[0] = fragmentation->fragmentationPlType[0];
260 uint32_t old_timestamp = rtp_sender_->Timestamp(); 271 memcpy(payload + 1, payload_data + fragmentation->fragmentationOffset[0],
261 rtpHeaderLength = rtp_sender_->BuildRtpHeader(data_buffer, red_payload_type, 272 fragmentation->fragmentationLength[0]);
262 marker_bit, capture_timestamp,
263 clock_->TimeInMilliseconds());
264
265 timestampOffset = uint16_t(rtp_sender_->Timestamp() - old_timestamp);
266 } else { 273 } else {
267 rtpHeaderLength = rtp_sender_->BuildRtpHeader(data_buffer, payload_type, 274 uint8_t* payload = packet->AllocatePayload(payload_size);
268 marker_bit, capture_timestamp, 275 if (!payload)
269 clock_->TimeInMilliseconds()); 276 return false;
270 } 277 memcpy(payload, payload_data, payload_size);
271 if (rtpHeaderLength <= 0) {
272 return false;
273 }
274 if (max_payload_length < (rtpHeaderLength + payload_size)) {
275 // Too large payload buffer.
276 return false;
277 }
278 if (red_payload_type >= 0 && // Have we configured RED?
279 fragmentation && fragmentation->fragmentationVectorSize > 1 &&
280 !marker_bit) {
281 if (timestampOffset <= 0x3fff) {
282 if (fragmentation->fragmentationVectorSize != 2) {
283 // we only support 2 codecs when using RED
284 return false;
285 }
286 // only 0x80 if we have multiple blocks
287 data_buffer[rtpHeaderLength++] =
288 0x80 + fragmentation->fragmentationPlType[1];
289 size_t blockLength = fragmentation->fragmentationLength[1];
290
291 // sanity blockLength
292 if (blockLength > 0x3ff) { // block length 10 bits 1023 bytes
293 return false;
294 }
295 uint32_t REDheader = (timestampOffset << 10) + blockLength;
296 ByteWriter<uint32_t>::WriteBigEndian(data_buffer + rtpHeaderLength,
297 REDheader);
298 rtpHeaderLength += 3;
299
300 data_buffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0];
301 // copy the RED data
302 memcpy(data_buffer + rtpHeaderLength,
303 payload_data + fragmentation->fragmentationOffset[1],
304 fragmentation->fragmentationLength[1]);
305
306 // copy the normal data
307 memcpy(
308 data_buffer + rtpHeaderLength + fragmentation->fragmentationLength[1],
309 payload_data + fragmentation->fragmentationOffset[0],
310 fragmentation->fragmentationLength[0]);
311
312 payload_size = fragmentation->fragmentationLength[0] +
313 fragmentation->fragmentationLength[1];
314 } else {
315 // silence for too long send only new data
316 data_buffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0];
317 memcpy(data_buffer + rtpHeaderLength,
318 payload_data + fragmentation->fragmentationOffset[0],
319 fragmentation->fragmentationLength[0]);
320
321 payload_size = fragmentation->fragmentationLength[0];
322 }
323 } else {
324 if (fragmentation && fragmentation->fragmentationVectorSize > 0) {
325 // use the fragment info if we have one
326 data_buffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0];
327 memcpy(data_buffer + rtpHeaderLength,
328 payload_data + fragmentation->fragmentationOffset[0],
329 fragmentation->fragmentationLength[0]);
330
331 payload_size = fragmentation->fragmentationLength[0];
332 } else {
333 memcpy(data_buffer + rtpHeaderLength, payload_data, payload_size);
334 }
335 } 278 }
336 279
337 { 280 {
338 rtc::CritScope cs(&send_audio_critsect_); 281 rtc::CritScope cs(&send_audio_critsect_);
339 last_payload_type_ = payload_type; 282 last_payload_type_ = payload_type;
340 } 283 }
341 // Update audio level extension, if included. 284 // Allocate sequence number.
342 size_t packetSize = payload_size + rtpHeaderLength; 285 rtp_sender_->PrepareToSend(packet.get());
343 RtpUtility::RtpHeaderParser rtp_parser(data_buffer, packetSize);
344 RTPHeader rtp_header;
345 rtp_parser.Parse(&rtp_header);
346 rtp_sender_->UpdateAudioLevel(data_buffer, packetSize, rtp_header,
347 (frame_type == kAudioFrameSpeech),
348 audio_level_dbov);
349 TRACE_EVENT_ASYNC_END2("webrtc", "Audio", capture_timestamp, "timestamp", 286 TRACE_EVENT_ASYNC_END2("webrtc", "Audio", capture_timestamp, "timestamp",
350 rtp_sender_->Timestamp(), "seqnum", 287 packet->Timestamp(), "seqnum",
351 rtp_sender_->SequenceNumber()); 288 packet->SequenceNumber());
352 bool send_result = rtp_sender_->SendToNetwork( 289 bool send_result = rtp_sender_->SendToNetwork(
353 data_buffer, payload_size, rtpHeaderLength, rtc::TimeMillis(), 290 std::move(packet), kAllowRetransmission, RtpPacketSender::kHighPriority);
354 kAllowRetransmission, RtpPacketSender::kHighPriority);
355 if (first_packet_sent_()) { 291 if (first_packet_sent_()) {
356 LOG(LS_INFO) << "First audio RTP packet sent to pacer"; 292 LOG(LS_INFO) << "First audio RTP packet sent to pacer";
357 } 293 }
358 return send_result; 294 return send_result;
359 } 295 }
360 296
361 // Audio level magnitude and voice activity flag are set for each RTP packet 297 // Audio level magnitude and voice activity flag are set for each RTP packet
362 int32_t RTPSenderAudio::SetAudioLevel(uint8_t level_dbov) { 298 int32_t RTPSenderAudio::SetAudioLevel(uint8_t level_dbov) {
363 if (level_dbov > 127) { 299 if (level_dbov > 127) {
364 return -1; 300 return -1;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 } 337 }
402 } 338 }
403 return AddDTMF(key, time_ms, level); 339 return AddDTMF(key, time_ms, level);
404 } 340 }
405 341
406 bool RTPSenderAudio::SendTelephoneEventPacket(bool ended, 342 bool RTPSenderAudio::SendTelephoneEventPacket(bool ended,
407 int8_t dtmf_payload_type, 343 int8_t dtmf_payload_type,
408 uint32_t dtmf_timestamp, 344 uint32_t dtmf_timestamp,
409 uint16_t duration, 345 uint16_t duration,
410 bool marker_bit) { 346 bool marker_bit) {
411 uint8_t dtmfbuffer[IP_PACKET_SIZE];
412 uint8_t send_count = 1; 347 uint8_t send_count = 1;
413 bool result = true; 348 bool result = true;
414 349
415 if (ended) { 350 if (ended) {
416 // resend last packet in an event 3 times 351 // resend last packet in an event 3 times
417 send_count = 3; 352 send_count = 3;
418 } 353 }
419 do { 354 do {
420 // Send DTMF data 355 // Send DTMF data
421 int32_t header_length = rtp_sender_->BuildRtpHeader( 356 std::unique_ptr<RtpPacketToSend> packet = rtp_sender_->AllocatePacket(true);
422 dtmfbuffer, dtmf_payload_type, marker_bit, dtmf_timestamp, 357 if (!packet)
423 clock_->TimeInMilliseconds());
424 if (header_length <= 0)
425 return false; 358 return false;
426 359 packet->SetPayloadType(dtmf_payload_type);
427 // reset CSRC and X bit 360 packet->SetMarker(marker_bit);
428 dtmfbuffer[0] &= 0xe0; 361 packet->SetTimestamp(dtmf_timestamp);
362 packet->set_capture_time_ms(clock_->TimeInMilliseconds());
429 363
430 // Create DTMF data 364 // Create DTMF data
431 /* From RFC 2833: 365 /* From RFC 2833:
432 366
433 0 1 2 3 367 0 1 2 3
434 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 368 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
435 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 369 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
436 | event |E|R| volume | duration | 370 | event |E|R| volume | duration |
437 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 371 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
438 */ 372 */
439 // R bit always cleared 373 // R bit always cleared
440 uint8_t R = 0x00; 374 uint8_t R = 0x00;
441 uint8_t volume = dtmf_level_; 375 uint8_t volume = dtmf_level_;
442 376
443 // First packet un-ended 377 // First packet un-ended
444 uint8_t E = ended ? 0x80 : 0x00; 378 uint8_t E = ended ? 0x80 : 0x00;
445 379
380 uint8_t* dtmfbuffer = packet->AllocatePayload(4);
381 RTC_DCHECK(dtmfbuffer);
446 // First byte is Event number, equals key number 382 // First byte is Event number, equals key number
447 dtmfbuffer[12] = dtmf_key_; 383 dtmfbuffer[0] = dtmf_key_;
448 dtmfbuffer[13] = E | R | volume; 384 dtmfbuffer[1] = E | R | volume;
449 ByteWriter<uint16_t>::WriteBigEndian(dtmfbuffer + 14, duration); 385 ByteWriter<uint16_t>::WriteBigEndian(dtmfbuffer + 2, duration);
386 if (!rtp_sender_->PrepareToSend(packet.get()))
387 return false;
450 388
451 TRACE_EVENT_INSTANT2( 389 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
452 TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "Audio::SendTelephoneEvent", 390 "Audio::SendTelephoneEvent", "timestamp",
453 "timestamp", dtmf_timestamp, "seqnum", rtp_sender_->SequenceNumber()); 391 dtmf_timestamp, "seqnum", packet->SequenceNumber());
454 result = rtp_sender_->SendToNetwork(dtmfbuffer, 4, 12, rtc::TimeMillis(), 392 result = rtp_sender_->SendToNetwork(std::move(packet), kAllowRetransmission,
455 kAllowRetransmission,
456 RtpPacketSender::kHighPriority); 393 RtpPacketSender::kHighPriority);
457 send_count--; 394 send_count--;
458 } while (send_count > 0 && result); 395 } while (send_count > 0 && result);
459 396
460 return result; 397 return result;
461 } 398 }
462 } // namespace webrtc 399 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698