| 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 |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |