| 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 17 matching lines...) Expand all Loading... |
| 28 packet_size_samples_(160), | 28 packet_size_samples_(160), |
| 29 dtmf_event_is_on_(false), | 29 dtmf_event_is_on_(false), |
| 30 dtmf_event_first_packet_sent_(false), | 30 dtmf_event_first_packet_sent_(false), |
| 31 dtmf_payload_type_(-1), | 31 dtmf_payload_type_(-1), |
| 32 dtmf_timestamp_(0), | 32 dtmf_timestamp_(0), |
| 33 dtmf_key_(0), | 33 dtmf_key_(0), |
| 34 dtmf_length_samples_(0), | 34 dtmf_length_samples_(0), |
| 35 dtmf_level_(0), | 35 dtmf_level_(0), |
| 36 dtmf_time_last_sent_(0), | 36 dtmf_time_last_sent_(0), |
| 37 dtmf_timestamp_last_sent_(0), | 37 dtmf_timestamp_last_sent_(0), |
| 38 red_payload_type_(-1), | |
| 39 inband_vad_active_(false), | 38 inband_vad_active_(false), |
| 40 cngnb_payload_type_(-1), | 39 cngnb_payload_type_(-1), |
| 41 cngwb_payload_type_(-1), | 40 cngwb_payload_type_(-1), |
| 42 cngswb_payload_type_(-1), | 41 cngswb_payload_type_(-1), |
| 43 cngfb_payload_type_(-1), | 42 cngfb_payload_type_(-1), |
| 44 last_payload_type_(-1), | 43 last_payload_type_(-1), |
| 45 audio_level_dbov_(0) {} | 44 audio_level_dbov_(0) {} |
| 46 | 45 |
| 47 RTPSenderAudio::~RTPSenderAudio() {} | 46 RTPSenderAudio::~RTPSenderAudio() {} |
| 48 | 47 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 int8_t payload_type, | 148 int8_t payload_type, |
| 150 uint32_t capture_timestamp, | 149 uint32_t capture_timestamp, |
| 151 const uint8_t* payload_data, | 150 const uint8_t* payload_data, |
| 152 size_t data_size, | 151 size_t data_size, |
| 153 const RTPFragmentationHeader* fragmentation) { | 152 const RTPFragmentationHeader* fragmentation) { |
| 154 // TODO(pwestin) Breakup function in smaller functions. | 153 // TODO(pwestin) Breakup function in smaller functions. |
| 155 size_t payload_size = data_size; | 154 size_t payload_size = data_size; |
| 156 size_t max_payload_length = rtp_sender_->MaxPayloadLength(); | 155 size_t max_payload_length = rtp_sender_->MaxPayloadLength(); |
| 157 uint16_t dtmf_length_ms = 0; | 156 uint16_t dtmf_length_ms = 0; |
| 158 uint8_t key = 0; | 157 uint8_t key = 0; |
| 159 int red_payload_type; | |
| 160 uint8_t audio_level_dbov; | 158 uint8_t audio_level_dbov; |
| 161 int8_t dtmf_payload_type; | 159 int8_t dtmf_payload_type; |
| 162 uint16_t packet_size_samples; | 160 uint16_t packet_size_samples; |
| 163 { | 161 { |
| 164 rtc::CritScope cs(&send_audio_critsect_); | 162 rtc::CritScope cs(&send_audio_critsect_); |
| 165 red_payload_type = red_payload_type_; | |
| 166 audio_level_dbov = audio_level_dbov_; | 163 audio_level_dbov = audio_level_dbov_; |
| 167 dtmf_payload_type = dtmf_payload_type_; | 164 dtmf_payload_type = dtmf_payload_type_; |
| 168 packet_size_samples = packet_size_samples_; | 165 packet_size_samples = packet_size_samples_; |
| 169 } | 166 } |
| 170 | 167 |
| 171 // Check if we have pending DTMFs to send | 168 // Check if we have pending DTMFs to send |
| 172 if (!dtmf_event_is_on_ && PendingDTMF()) { | 169 if (!dtmf_event_is_on_ && PendingDTMF()) { |
| 173 int64_t delaySinceLastDTMF = | 170 int64_t delaySinceLastDTMF = |
| 174 clock_->TimeInMilliseconds() - dtmf_time_last_sent_; | 171 clock_->TimeInMilliseconds() - dtmf_time_last_sent_; |
| 175 | 172 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 // we don't send empty audio RTP packets | 241 // we don't send empty audio RTP packets |
| 245 // no error since we use it to drive DTMF when we use VAD | 242 // no error since we use it to drive DTMF when we use VAD |
| 246 return true; | 243 return true; |
| 247 } | 244 } |
| 248 return false; | 245 return false; |
| 249 } | 246 } |
| 250 uint8_t data_buffer[IP_PACKET_SIZE]; | 247 uint8_t data_buffer[IP_PACKET_SIZE]; |
| 251 bool marker_bit = MarkerBit(frame_type, payload_type); | 248 bool marker_bit = MarkerBit(frame_type, payload_type); |
| 252 | 249 |
| 253 int32_t rtpHeaderLength = 0; | 250 int32_t rtpHeaderLength = 0; |
| 254 uint16_t timestampOffset = 0; | |
| 255 | 251 |
| 256 if (red_payload_type >= 0 && fragmentation && !marker_bit && | 252 rtpHeaderLength = rtp_sender_->BuildRtpHeader(data_buffer, payload_type, |
| 257 fragmentation->fragmentationVectorSize > 1) { | 253 marker_bit, capture_timestamp, |
| 258 // have we configured RED? use its payload type | 254 clock_->TimeInMilliseconds()); |
| 259 // we need to get the current timestamp to calc the diff | |
| 260 uint32_t old_timestamp = rtp_sender_->Timestamp(); | |
| 261 rtpHeaderLength = rtp_sender_->BuildRtpHeader(data_buffer, red_payload_type, | |
| 262 marker_bit, capture_timestamp, | |
| 263 clock_->TimeInMilliseconds()); | |
| 264 | |
| 265 timestampOffset = uint16_t(rtp_sender_->Timestamp() - old_timestamp); | |
| 266 } else { | |
| 267 rtpHeaderLength = rtp_sender_->BuildRtpHeader(data_buffer, payload_type, | |
| 268 marker_bit, capture_timestamp, | |
| 269 clock_->TimeInMilliseconds()); | |
| 270 } | |
| 271 if (rtpHeaderLength <= 0) { | 255 if (rtpHeaderLength <= 0) { |
| 272 return false; | 256 return false; |
| 273 } | 257 } |
| 274 if (max_payload_length < (rtpHeaderLength + payload_size)) { | 258 if (max_payload_length < (rtpHeaderLength + payload_size)) { |
| 275 // Too large payload buffer. | 259 // Too large payload buffer. |
| 276 return false; | 260 return false; |
| 277 } | 261 } |
| 278 if (red_payload_type >= 0 && // Have we configured RED? | 262 if (fragmentation && fragmentation->fragmentationVectorSize > 0) { |
| 279 fragmentation && fragmentation->fragmentationVectorSize > 1 && | 263 // use the fragment info if we have one |
| 280 !marker_bit) { | 264 data_buffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0]; |
| 281 if (timestampOffset <= 0x3fff) { | 265 memcpy(data_buffer + rtpHeaderLength, |
| 282 if (fragmentation->fragmentationVectorSize != 2) { | 266 payload_data + fragmentation->fragmentationOffset[0], |
| 283 // we only support 2 codecs when using RED | 267 fragmentation->fragmentationLength[0]); |
| 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 | 268 |
| 291 // sanity blockLength | 269 payload_size = fragmentation->fragmentationLength[0]; |
| 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 { | 270 } else { |
| 324 if (fragmentation && fragmentation->fragmentationVectorSize > 0) { | 271 memcpy(data_buffer + rtpHeaderLength, payload_data, payload_size); |
| 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 } | 272 } |
| 336 | 273 |
| 337 { | 274 { |
| 338 rtc::CritScope cs(&send_audio_critsect_); | 275 rtc::CritScope cs(&send_audio_critsect_); |
| 339 last_payload_type_ = payload_type; | 276 last_payload_type_ = payload_type; |
| 340 } | 277 } |
| 341 // Update audio level extension, if included. | 278 // Update audio level extension, if included. |
| 342 size_t packetSize = payload_size + rtpHeaderLength; | 279 size_t packetSize = payload_size + rtpHeaderLength; |
| 343 RtpUtility::RtpHeaderParser rtp_parser(data_buffer, packetSize); | 280 RtpUtility::RtpHeaderParser rtp_parser(data_buffer, packetSize); |
| 344 RTPHeader rtp_header; | 281 RTPHeader rtp_header; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 361 // Audio level magnitude and voice activity flag are set for each RTP packet | 298 // Audio level magnitude and voice activity flag are set for each RTP packet |
| 362 int32_t RTPSenderAudio::SetAudioLevel(uint8_t level_dbov) { | 299 int32_t RTPSenderAudio::SetAudioLevel(uint8_t level_dbov) { |
| 363 if (level_dbov > 127) { | 300 if (level_dbov > 127) { |
| 364 return -1; | 301 return -1; |
| 365 } | 302 } |
| 366 rtc::CritScope cs(&send_audio_critsect_); | 303 rtc::CritScope cs(&send_audio_critsect_); |
| 367 audio_level_dbov_ = level_dbov; | 304 audio_level_dbov_ = level_dbov; |
| 368 return 0; | 305 return 0; |
| 369 } | 306 } |
| 370 | 307 |
| 371 // Set payload type for Redundant Audio Data RFC 2198 | |
| 372 int32_t RTPSenderAudio::SetRED(int8_t payload_type) { | |
| 373 if (payload_type < -1) { | |
| 374 return -1; | |
| 375 } | |
| 376 rtc::CritScope cs(&send_audio_critsect_); | |
| 377 red_payload_type_ = payload_type; | |
| 378 return 0; | |
| 379 } | |
| 380 | |
| 381 // Get payload type for Redundant Audio Data RFC 2198 | |
| 382 int32_t RTPSenderAudio::RED(int8_t* payload_type) const { | |
| 383 rtc::CritScope cs(&send_audio_critsect_); | |
| 384 if (red_payload_type_ == -1) { | |
| 385 // not configured | |
| 386 return -1; | |
| 387 } | |
| 388 *payload_type = red_payload_type_; | |
| 389 return 0; | |
| 390 } | |
| 391 | |
| 392 // Send a TelephoneEvent tone using RFC 2833 (4733) | 308 // Send a TelephoneEvent tone using RFC 2833 (4733) |
| 393 int32_t RTPSenderAudio::SendTelephoneEvent(uint8_t key, | 309 int32_t RTPSenderAudio::SendTelephoneEvent(uint8_t key, |
| 394 uint16_t time_ms, | 310 uint16_t time_ms, |
| 395 uint8_t level) { | 311 uint8_t level) { |
| 396 { | 312 { |
| 397 rtc::CritScope lock(&send_audio_critsect_); | 313 rtc::CritScope lock(&send_audio_critsect_); |
| 398 if (dtmf_payload_type_ < 0) { | 314 if (dtmf_payload_type_ < 0) { |
| 399 // TelephoneEvent payloadtype not configured | 315 // TelephoneEvent payloadtype not configured |
| 400 return -1; | 316 return -1; |
| 401 } | 317 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 453 "timestamp", dtmf_timestamp, "seqnum", rtp_sender_->SequenceNumber()); | 369 "timestamp", dtmf_timestamp, "seqnum", rtp_sender_->SequenceNumber()); |
| 454 result = rtp_sender_->SendToNetwork(dtmfbuffer, 4, 12, rtc::TimeMillis(), | 370 result = rtp_sender_->SendToNetwork(dtmfbuffer, 4, 12, rtc::TimeMillis(), |
| 455 kAllowRetransmission, | 371 kAllowRetransmission, |
| 456 RtpPacketSender::kHighPriority); | 372 RtpPacketSender::kHighPriority); |
| 457 send_count--; | 373 send_count--; |
| 458 } while (send_count > 0 && result); | 374 } while (send_count > 0 && result); |
| 459 | 375 |
| 460 return result; | 376 return result; |
| 461 } | 377 } |
| 462 } // namespace webrtc | 378 } // namespace webrtc |
| OLD | NEW |