| 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 <memory> |
| 16 #include <utility> |
| 17 |
| 15 #include "webrtc/base/logging.h" | 18 #include "webrtc/base/logging.h" |
| 16 #include "webrtc/base/timeutils.h" | 19 #include "webrtc/base/timeutils.h" |
| 17 #include "webrtc/base/trace_event.h" | 20 #include "webrtc/base/trace_event.h" |
| 18 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" | 21 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" |
| 19 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | 22 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" |
| 23 #include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h" |
| 24 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_to_send.h" |
| 20 | 25 |
| 21 namespace webrtc { | 26 namespace webrtc { |
| 22 | 27 |
| 23 static const int kDtmfFrequencyHz = 8000; | 28 static const int kDtmfFrequencyHz = 8000; |
| 24 | 29 |
| 25 RTPSenderAudio::RTPSenderAudio(Clock* clock, RTPSender* rtp_sender) | 30 RTPSenderAudio::RTPSenderAudio(Clock* clock, RTPSender* rtp_sender) |
| 26 : clock_(clock), | 31 : clock_(clock), |
| 27 rtp_sender_(rtp_sender), | 32 rtp_sender_(rtp_sender), |
| 28 packet_size_samples_(160), | 33 packet_size_samples_(160), |
| 29 dtmf_event_is_on_(false), | 34 dtmf_event_is_on_(false), |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 inband_vad_active_ = false; | 146 inband_vad_active_ = false; |
| 142 marker_bit = true; | 147 marker_bit = true; |
| 143 } | 148 } |
| 144 return marker_bit; | 149 return marker_bit; |
| 145 } | 150 } |
| 146 | 151 |
| 147 bool RTPSenderAudio::SendAudio(FrameType frame_type, | 152 bool RTPSenderAudio::SendAudio(FrameType frame_type, |
| 148 int8_t payload_type, | 153 int8_t payload_type, |
| 149 uint32_t rtp_timestamp, | 154 uint32_t rtp_timestamp, |
| 150 const uint8_t* payload_data, | 155 const uint8_t* payload_data, |
| 151 size_t data_size, | 156 size_t payload_size, |
| 152 const RTPFragmentationHeader* fragmentation) { | 157 const RTPFragmentationHeader* fragmentation) { |
| 153 // TODO(pwestin) Breakup function in smaller functions. | 158 // TODO(pwestin) Breakup function in smaller functions. |
| 154 size_t payload_size = data_size; | |
| 155 size_t max_payload_length = rtp_sender_->MaxPayloadLength(); | |
| 156 uint16_t dtmf_length_ms = 0; | 159 uint16_t dtmf_length_ms = 0; |
| 157 uint8_t key = 0; | 160 uint8_t key = 0; |
| 158 uint8_t audio_level_dbov; | 161 uint8_t audio_level_dbov; |
| 159 int8_t dtmf_payload_type; | 162 int8_t dtmf_payload_type; |
| 160 uint16_t packet_size_samples; | 163 uint16_t packet_size_samples; |
| 161 { | 164 { |
| 162 rtc::CritScope cs(&send_audio_critsect_); | 165 rtc::CritScope cs(&send_audio_critsect_); |
| 163 audio_level_dbov = audio_level_dbov_; | 166 audio_level_dbov = audio_level_dbov_; |
| 164 dtmf_payload_type = dtmf_payload_type_; | 167 dtmf_payload_type = dtmf_payload_type_; |
| 165 packet_size_samples = packet_size_samples_; | 168 packet_size_samples = packet_size_samples_; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 return true; | 239 return true; |
| 237 } | 240 } |
| 238 if (payload_size == 0 || payload_data == NULL) { | 241 if (payload_size == 0 || payload_data == NULL) { |
| 239 if (frame_type == kEmptyFrame) { | 242 if (frame_type == kEmptyFrame) { |
| 240 // we don't send empty audio RTP packets | 243 // we don't send empty audio RTP packets |
| 241 // no error since we use it to drive DTMF when we use VAD | 244 // no error since we use it to drive DTMF when we use VAD |
| 242 return true; | 245 return true; |
| 243 } | 246 } |
| 244 return false; | 247 return false; |
| 245 } | 248 } |
| 246 uint8_t data_buffer[IP_PACKET_SIZE]; | 249 std::unique_ptr<RtpPacketToSend> packet = rtp_sender_->AllocatePacket(); |
| 247 bool marker_bit = MarkerBit(frame_type, payload_type); | 250 packet->SetMarker(MarkerBit(frame_type, payload_type)); |
| 251 packet->SetPayloadType(payload_type); |
| 252 packet->SetTimestamp(rtp_timestamp); |
| 253 packet->set_capture_time_ms(clock_->TimeInMilliseconds()); |
| 254 // Update audio level extension, if included. |
| 255 packet->SetExtension<AudioLevel>(frame_type == kAudioFrameSpeech, |
| 256 audio_level_dbov); |
| 248 | 257 |
| 249 int32_t rtpHeaderLength = 0; | 258 if (fragmentation && fragmentation->fragmentationVectorSize > 0) { |
| 259 // Use the fragment info if we have one. |
| 260 uint8_t* payload = |
| 261 packet->AllocatePayload(1 + fragmentation->fragmentationLength[0]); |
| 262 if (!payload) // Too large payload buffer. |
| 263 return false; |
| 264 payload[0] = fragmentation->fragmentationPlType[0]; |
| 265 memcpy(payload + 1, payload_data + fragmentation->fragmentationOffset[0], |
| 266 fragmentation->fragmentationLength[0]); |
| 267 } else { |
| 268 uint8_t* payload = packet->AllocatePayload(payload_size); |
| 269 if (!payload) // Too large payload buffer. |
| 270 return false; |
| 271 memcpy(payload, payload_data, payload_size); |
| 272 } |
| 250 | 273 |
| 251 rtpHeaderLength = | 274 if (!rtp_sender_->AssignSequenceNumber(packet.get())) |
| 252 rtp_sender_->BuildRtpHeader(data_buffer, payload_type, marker_bit, | |
| 253 rtp_timestamp, clock_->TimeInMilliseconds()); | |
| 254 if (rtpHeaderLength <= 0) { | |
| 255 return false; | 275 return false; |
| 256 } | |
| 257 if (max_payload_length < (rtpHeaderLength + payload_size)) { | |
| 258 // Too large payload buffer. | |
| 259 return false; | |
| 260 } | |
| 261 if (fragmentation && fragmentation->fragmentationVectorSize > 0) { | |
| 262 // use the fragment info if we have one | |
| 263 data_buffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0]; | |
| 264 memcpy(data_buffer + rtpHeaderLength, | |
| 265 payload_data + fragmentation->fragmentationOffset[0], | |
| 266 fragmentation->fragmentationLength[0]); | |
| 267 | |
| 268 payload_size = fragmentation->fragmentationLength[0]; | |
| 269 } else { | |
| 270 memcpy(data_buffer + rtpHeaderLength, payload_data, payload_size); | |
| 271 } | |
| 272 | 276 |
| 273 { | 277 { |
| 274 rtc::CritScope cs(&send_audio_critsect_); | 278 rtc::CritScope cs(&send_audio_critsect_); |
| 275 last_payload_type_ = payload_type; | 279 last_payload_type_ = payload_type; |
| 276 } | 280 } |
| 277 // Update audio level extension, if included. | |
| 278 size_t packetSize = payload_size + rtpHeaderLength; | |
| 279 RtpUtility::RtpHeaderParser rtp_parser(data_buffer, packetSize); | |
| 280 RTPHeader rtp_header; | |
| 281 rtp_parser.Parse(&rtp_header); | |
| 282 rtp_sender_->UpdateAudioLevel(data_buffer, packetSize, rtp_header, | |
| 283 (frame_type == kAudioFrameSpeech), | |
| 284 audio_level_dbov); | |
| 285 TRACE_EVENT_ASYNC_END2("webrtc", "Audio", rtp_timestamp, "timestamp", | 281 TRACE_EVENT_ASYNC_END2("webrtc", "Audio", rtp_timestamp, "timestamp", |
| 286 rtp_timestamp, "seqnum", | 282 packet->Timestamp(), "seqnum", |
| 287 rtp_sender_->SequenceNumber()); | 283 packet->SequenceNumber()); |
| 288 bool send_result = rtp_sender_->SendToNetwork( | 284 bool send_result = rtp_sender_->SendToNetwork( |
| 289 data_buffer, payload_size, rtpHeaderLength, rtc::TimeMillis(), | 285 std::move(packet), kAllowRetransmission, RtpPacketSender::kHighPriority); |
| 290 kAllowRetransmission, RtpPacketSender::kHighPriority); | |
| 291 if (first_packet_sent_()) { | 286 if (first_packet_sent_()) { |
| 292 LOG(LS_INFO) << "First audio RTP packet sent to pacer"; | 287 LOG(LS_INFO) << "First audio RTP packet sent to pacer"; |
| 293 } | 288 } |
| 294 return send_result; | 289 return send_result; |
| 295 } | 290 } |
| 296 | 291 |
| 297 // Audio level magnitude and voice activity flag are set for each RTP packet | 292 // Audio level magnitude and voice activity flag are set for each RTP packet |
| 298 int32_t RTPSenderAudio::SetAudioLevel(uint8_t level_dbov) { | 293 int32_t RTPSenderAudio::SetAudioLevel(uint8_t level_dbov) { |
| 299 if (level_dbov > 127) { | 294 if (level_dbov > 127) { |
| 300 return -1; | 295 return -1; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 316 } | 311 } |
| 317 } | 312 } |
| 318 return AddDTMF(key, time_ms, level); | 313 return AddDTMF(key, time_ms, level); |
| 319 } | 314 } |
| 320 | 315 |
| 321 bool RTPSenderAudio::SendTelephoneEventPacket(bool ended, | 316 bool RTPSenderAudio::SendTelephoneEventPacket(bool ended, |
| 322 int8_t dtmf_payload_type, | 317 int8_t dtmf_payload_type, |
| 323 uint32_t dtmf_timestamp, | 318 uint32_t dtmf_timestamp, |
| 324 uint16_t duration, | 319 uint16_t duration, |
| 325 bool marker_bit) { | 320 bool marker_bit) { |
| 326 uint8_t dtmfbuffer[IP_PACKET_SIZE]; | |
| 327 uint8_t send_count = 1; | 321 uint8_t send_count = 1; |
| 328 bool result = true; | 322 bool result = true; |
| 329 | 323 |
| 330 if (ended) { | 324 if (ended) { |
| 331 // resend last packet in an event 3 times | 325 // resend last packet in an event 3 times |
| 332 send_count = 3; | 326 send_count = 3; |
| 333 } | 327 } |
| 334 do { | 328 do { |
| 335 // Send DTMF data | 329 // Send DTMF data. |
| 336 int32_t header_length = rtp_sender_->BuildRtpHeader( | 330 std::unique_ptr<RtpPacketToSend> packet(new RtpPacketToSend(nullptr, 16)); |
| 337 dtmfbuffer, dtmf_payload_type, marker_bit, dtmf_timestamp, | 331 packet->SetPayloadType(dtmf_payload_type); |
| 338 clock_->TimeInMilliseconds()); | 332 packet->SetMarker(marker_bit); |
| 339 if (header_length <= 0) | 333 packet->SetSsrc(rtp_sender_->SSRC()); |
| 334 packet->SetTimestamp(dtmf_timestamp); |
| 335 packet->set_capture_time_ms(clock_->TimeInMilliseconds()); |
| 336 if (!rtp_sender_->AssignSequenceNumber(packet.get())) |
| 340 return false; | 337 return false; |
| 341 | 338 |
| 342 // reset CSRC and X bit | 339 // Create DTMF data. |
| 343 dtmfbuffer[0] &= 0xe0; | 340 uint8_t* dtmfbuffer = packet->AllocatePayload(4); |
| 344 | 341 RTC_DCHECK(dtmfbuffer); |
| 345 // Create DTMF data | |
| 346 /* From RFC 2833: | 342 /* From RFC 2833: |
| 347 | |
| 348 0 1 2 3 | 343 0 1 2 3 |
| 349 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 | 344 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 |
| 350 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 345 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 351 | event |E|R| volume | duration | | 346 | event |E|R| volume | duration | |
| 352 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 347 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 353 */ | 348 */ |
| 354 // R bit always cleared | 349 // R bit always cleared |
| 355 uint8_t R = 0x00; | 350 uint8_t R = 0x00; |
| 356 uint8_t volume = dtmf_level_; | 351 uint8_t volume = dtmf_level_; |
| 357 | 352 |
| 358 // First packet un-ended | 353 // First packet un-ended |
| 359 uint8_t E = ended ? 0x80 : 0x00; | 354 uint8_t E = ended ? 0x80 : 0x00; |
| 360 | 355 |
| 361 // First byte is Event number, equals key number | 356 // First byte is Event number, equals key number |
| 362 dtmfbuffer[12] = dtmf_key_; | 357 dtmfbuffer[0] = dtmf_key_; |
| 363 dtmfbuffer[13] = E | R | volume; | 358 dtmfbuffer[1] = E | R | volume; |
| 364 ByteWriter<uint16_t>::WriteBigEndian(dtmfbuffer + 14, duration); | 359 ByteWriter<uint16_t>::WriteBigEndian(dtmfbuffer + 2, duration); |
| 365 | 360 |
| 366 TRACE_EVENT_INSTANT2( | 361 TRACE_EVENT_INSTANT2( |
| 367 TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "Audio::SendTelephoneEvent", | 362 TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "Audio::SendTelephoneEvent", |
| 368 "timestamp", dtmf_timestamp, "seqnum", rtp_sender_->SequenceNumber()); | 363 "timestamp", packet->Timestamp(), "seqnum", packet->SequenceNumber()); |
| 369 result = rtp_sender_->SendToNetwork(dtmfbuffer, 4, 12, rtc::TimeMillis(), | 364 result = rtp_sender_->SendToNetwork(std::move(packet), kAllowRetransmission, |
| 370 kAllowRetransmission, | |
| 371 RtpPacketSender::kHighPriority); | 365 RtpPacketSender::kHighPriority); |
| 372 send_count--; | 366 send_count--; |
| 373 } while (send_count > 0 && result); | 367 } while (send_count > 0 && result); |
| 374 | 368 |
| 375 return result; | 369 return result; |
| 376 } | 370 } |
| 377 } // namespace webrtc | 371 } // namespace webrtc |
| OLD | NEW |