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

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

Issue 2089773002: Add EncodedImageCallback::OnEncodedImage(). (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: . 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
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 // For G.723 G.729, AMR etc we can have inband VAD 138 // For G.723 G.729, AMR etc we can have inband VAD
139 if (frame_type == kAudioFrameCN) { 139 if (frame_type == kAudioFrameCN) {
140 inband_vad_active_ = true; 140 inband_vad_active_ = true;
141 } else if (inband_vad_active_) { 141 } else if (inband_vad_active_) {
142 inband_vad_active_ = false; 142 inband_vad_active_ = false;
143 marker_bit = true; 143 marker_bit = true;
144 } 144 }
145 return marker_bit; 145 return marker_bit;
146 } 146 }
147 147
148 int32_t RTPSenderAudio::SendAudio(FrameType frame_type, 148 bool RTPSenderAudio::SendAudio(FrameType frame_type,
149 int8_t payload_type, 149 int8_t payload_type,
150 uint32_t capture_timestamp, 150 uint32_t capture_timestamp,
151 const uint8_t* payload_data, 151 const uint8_t* payload_data,
152 size_t data_size, 152 size_t data_size,
153 const RTPFragmentationHeader* fragmentation) { 153 const RTPFragmentationHeader* fragmentation) {
154 // TODO(pwestin) Breakup function in smaller functions. 154 // TODO(pwestin) Breakup function in smaller functions.
155 size_t payload_size = data_size; 155 size_t payload_size = data_size;
156 size_t max_payload_length = rtp_sender_->MaxPayloadLength(); 156 size_t max_payload_length = rtp_sender_->MaxPayloadLength();
157 uint16_t dtmf_length_ms = 0; 157 uint16_t dtmf_length_ms = 0;
158 uint8_t key = 0; 158 uint8_t key = 0;
(...skipping 29 matching lines...) Expand all
188 // A source MAY send events and coded audio packets for the same time 188 // A source MAY send events and coded audio packets for the same time
189 // but we don't support it 189 // but we don't support it
190 if (dtmf_event_is_on_) { 190 if (dtmf_event_is_on_) {
191 if (frame_type == kEmptyFrame) { 191 if (frame_type == kEmptyFrame) {
192 // kEmptyFrame is used to drive the DTMF when in CN mode 192 // kEmptyFrame is used to drive the DTMF when in CN mode
193 // it can be triggered more frequently than we want to send the 193 // it can be triggered more frequently than we want to send the
194 // DTMF packets. 194 // DTMF packets.
195 if (packet_size_samples > 195 if (packet_size_samples >
196 (capture_timestamp - dtmf_timestamp_last_sent_)) { 196 (capture_timestamp - dtmf_timestamp_last_sent_)) {
197 // not time to send yet 197 // not time to send yet
198 return 0; 198 return true;
199 } 199 }
200 } 200 }
201 dtmf_timestamp_last_sent_ = capture_timestamp; 201 dtmf_timestamp_last_sent_ = capture_timestamp;
202 uint32_t dtmf_duration_samples = capture_timestamp - dtmf_timestamp_; 202 uint32_t dtmf_duration_samples = capture_timestamp - dtmf_timestamp_;
203 bool ended = false; 203 bool ended = false;
204 bool send = true; 204 bool send = true;
205 205
206 if (dtmf_length_samples_ > dtmf_duration_samples) { 206 if (dtmf_length_samples_ > dtmf_duration_samples) {
207 if (dtmf_duration_samples <= 0) { 207 if (dtmf_duration_samples <= 0) {
208 // Skip send packet at start, since we shouldn't use duration 0 208 // Skip send packet at start, since we shouldn't use duration 0
(...skipping 12 matching lines...) Expand all
221 221
222 // set new timestap for this segment 222 // set new timestap for this segment
223 dtmf_timestamp_ = capture_timestamp; 223 dtmf_timestamp_ = capture_timestamp;
224 dtmf_duration_samples -= 0xffff; 224 dtmf_duration_samples -= 0xffff;
225 dtmf_length_samples_ -= 0xffff; 225 dtmf_length_samples_ -= 0xffff;
226 226
227 return SendTelephoneEventPacket( 227 return SendTelephoneEventPacket(
228 ended, dtmf_payload_type, dtmf_timestamp_, 228 ended, dtmf_payload_type, dtmf_timestamp_,
229 static_cast<uint16_t>(dtmf_duration_samples), false); 229 static_cast<uint16_t>(dtmf_duration_samples), false);
230 } else { 230 } else {
231 if (SendTelephoneEventPacket(ended, dtmf_payload_type, dtmf_timestamp_, 231 if (!SendTelephoneEventPacket(ended, dtmf_payload_type, dtmf_timestamp_,
232 dtmf_duration_samples, 232 dtmf_duration_samples,
233 !dtmf_event_first_packet_sent_) != 0) { 233 !dtmf_event_first_packet_sent_)) {
234 return -1; 234 return false;
235 } 235 }
236 dtmf_event_first_packet_sent_ = true; 236 dtmf_event_first_packet_sent_ = true;
237 return 0; 237 return true;
238 } 238 }
239 } 239 }
240 return 0; 240 return true;
241 } 241 }
242 if (payload_size == 0 || payload_data == NULL) { 242 if (payload_size == 0 || payload_data == NULL) {
243 if (frame_type == kEmptyFrame) { 243 if (frame_type == kEmptyFrame) {
244 // we don't send empty audio RTP packets 244 // we don't send empty audio RTP packets
245 // no error since we use it to drive DTMF when we use VAD 245 // no error since we use it to drive DTMF when we use VAD
246 return 0; 246 return true;
247 } 247 }
248 return -1; 248 return false;
249 } 249 }
250 uint8_t data_buffer[IP_PACKET_SIZE]; 250 uint8_t data_buffer[IP_PACKET_SIZE];
251 bool marker_bit = MarkerBit(frame_type, payload_type); 251 bool marker_bit = MarkerBit(frame_type, payload_type);
252 252
253 int32_t rtpHeaderLength = 0; 253 int32_t rtpHeaderLength = 0;
254 uint16_t timestampOffset = 0; 254 uint16_t timestampOffset = 0;
255 255
256 if (red_payload_type >= 0 && fragmentation && !marker_bit && 256 if (red_payload_type >= 0 && fragmentation && !marker_bit &&
257 fragmentation->fragmentationVectorSize > 1) { 257 fragmentation->fragmentationVectorSize > 1) {
258 // have we configured RED? use its payload type 258 // have we configured RED? use its payload type
259 // we need to get the current timestamp to calc the diff 259 // we need to get the current timestamp to calc the diff
260 uint32_t old_timestamp = rtp_sender_->Timestamp(); 260 uint32_t old_timestamp = rtp_sender_->Timestamp();
261 rtpHeaderLength = rtp_sender_->BuildRtpHeader(data_buffer, red_payload_type, 261 rtpHeaderLength = rtp_sender_->BuildRtpHeader(data_buffer, red_payload_type,
262 marker_bit, capture_timestamp, 262 marker_bit, capture_timestamp,
263 clock_->TimeInMilliseconds()); 263 clock_->TimeInMilliseconds());
264 264
265 timestampOffset = uint16_t(rtp_sender_->Timestamp() - old_timestamp); 265 timestampOffset = uint16_t(rtp_sender_->Timestamp() - old_timestamp);
266 } else { 266 } else {
267 rtpHeaderLength = rtp_sender_->BuildRtpHeader(data_buffer, payload_type, 267 rtpHeaderLength = rtp_sender_->BuildRtpHeader(data_buffer, payload_type,
268 marker_bit, capture_timestamp, 268 marker_bit, capture_timestamp,
269 clock_->TimeInMilliseconds()); 269 clock_->TimeInMilliseconds());
270 } 270 }
271 if (rtpHeaderLength <= 0) { 271 if (rtpHeaderLength <= 0) {
272 return -1; 272 return false;
273 } 273 }
274 if (max_payload_length < (rtpHeaderLength + payload_size)) { 274 if (max_payload_length < (rtpHeaderLength + payload_size)) {
275 // Too large payload buffer. 275 // Too large payload buffer.
276 return -1; 276 return false;
277 } 277 }
278 if (red_payload_type >= 0 && // Have we configured RED? 278 if (red_payload_type >= 0 && // Have we configured RED?
279 fragmentation && fragmentation->fragmentationVectorSize > 1 && 279 fragmentation && fragmentation->fragmentationVectorSize > 1 &&
280 !marker_bit) { 280 !marker_bit) {
281 if (timestampOffset <= 0x3fff) { 281 if (timestampOffset <= 0x3fff) {
282 if (fragmentation->fragmentationVectorSize != 2) { 282 if (fragmentation->fragmentationVectorSize != 2) {
283 // we only support 2 codecs when using RED 283 // we only support 2 codecs when using RED
284 return -1; 284 return false;
285 } 285 }
286 // only 0x80 if we have multiple blocks 286 // only 0x80 if we have multiple blocks
287 data_buffer[rtpHeaderLength++] = 287 data_buffer[rtpHeaderLength++] =
288 0x80 + fragmentation->fragmentationPlType[1]; 288 0x80 + fragmentation->fragmentationPlType[1];
289 size_t blockLength = fragmentation->fragmentationLength[1]; 289 size_t blockLength = fragmentation->fragmentationLength[1];
290 290
291 // sanity blockLength 291 // sanity blockLength
292 if (blockLength > 0x3ff) { // block length 10 bits 1023 bytes 292 if (blockLength > 0x3ff) { // block length 10 bits 1023 bytes
293 return -1; 293 return false;
294 } 294 }
295 uint32_t REDheader = (timestampOffset << 10) + blockLength; 295 uint32_t REDheader = (timestampOffset << 10) + blockLength;
296 ByteWriter<uint32_t>::WriteBigEndian(data_buffer + rtpHeaderLength, 296 ByteWriter<uint32_t>::WriteBigEndian(data_buffer + rtpHeaderLength,
297 REDheader); 297 REDheader);
298 rtpHeaderLength += 3; 298 rtpHeaderLength += 3;
299 299
300 data_buffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0]; 300 data_buffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0];
301 // copy the RED data 301 // copy the RED data
302 memcpy(data_buffer + rtpHeaderLength, 302 memcpy(data_buffer + rtpHeaderLength,
303 payload_data + fragmentation->fragmentationOffset[1], 303 payload_data + fragmentation->fragmentationOffset[1],
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 size_t packetSize = payload_size + rtpHeaderLength; 342 size_t packetSize = payload_size + rtpHeaderLength;
343 RtpUtility::RtpHeaderParser rtp_parser(data_buffer, packetSize); 343 RtpUtility::RtpHeaderParser rtp_parser(data_buffer, packetSize);
344 RTPHeader rtp_header; 344 RTPHeader rtp_header;
345 rtp_parser.Parse(&rtp_header); 345 rtp_parser.Parse(&rtp_header);
346 rtp_sender_->UpdateAudioLevel(data_buffer, packetSize, rtp_header, 346 rtp_sender_->UpdateAudioLevel(data_buffer, packetSize, rtp_header,
347 (frame_type == kAudioFrameSpeech), 347 (frame_type == kAudioFrameSpeech),
348 audio_level_dbov); 348 audio_level_dbov);
349 TRACE_EVENT_ASYNC_END2("webrtc", "Audio", capture_timestamp, "timestamp", 349 TRACE_EVENT_ASYNC_END2("webrtc", "Audio", capture_timestamp, "timestamp",
350 rtp_sender_->Timestamp(), "seqnum", 350 rtp_sender_->Timestamp(), "seqnum",
351 rtp_sender_->SequenceNumber()); 351 rtp_sender_->SequenceNumber());
352 int32_t send_result = rtp_sender_->SendToNetwork( 352 bool send_result = rtp_sender_->SendToNetwork(
353 data_buffer, payload_size, rtpHeaderLength, rtc::TimeMillis(), 353 data_buffer, payload_size, rtpHeaderLength, rtc::TimeMillis(),
354 kAllowRetransmission, RtpPacketSender::kHighPriority); 354 kAllowRetransmission, RtpPacketSender::kHighPriority);
355 if (first_packet_sent_()) { 355 if (first_packet_sent_()) {
356 LOG(LS_INFO) << "First audio RTP packet sent to pacer"; 356 LOG(LS_INFO) << "First audio RTP packet sent to pacer";
357 } 357 }
358 return send_result; 358 return send_result;
359 } 359 }
360 360
361 // Audio level magnitude and voice activity flag are set for each RTP packet 361 // Audio level magnitude and voice activity flag are set for each RTP packet
362 int32_t RTPSenderAudio::SetAudioLevel(uint8_t level_dbov) { 362 int32_t RTPSenderAudio::SetAudioLevel(uint8_t level_dbov) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 { 396 {
397 rtc::CritScope lock(&send_audio_critsect_); 397 rtc::CritScope lock(&send_audio_critsect_);
398 if (dtmf_payload_type_ < 0) { 398 if (dtmf_payload_type_ < 0) {
399 // TelephoneEvent payloadtype not configured 399 // TelephoneEvent payloadtype not configured
400 return -1; 400 return -1;
401 } 401 }
402 } 402 }
403 return AddDTMF(key, time_ms, level); 403 return AddDTMF(key, time_ms, level);
404 } 404 }
405 405
406 int32_t RTPSenderAudio::SendTelephoneEventPacket(bool ended, 406 bool RTPSenderAudio::SendTelephoneEventPacket(bool ended,
407 int8_t dtmf_payload_type, 407 int8_t dtmf_payload_type,
408 uint32_t dtmf_timestamp, 408 uint32_t dtmf_timestamp,
409 uint16_t duration, 409 uint16_t duration,
410 bool marker_bit) { 410 bool marker_bit) {
411 uint8_t dtmfbuffer[IP_PACKET_SIZE]; 411 uint8_t dtmfbuffer[IP_PACKET_SIZE];
412 uint8_t sendCount = 1; 412 uint8_t send_count = 1;
413 int32_t retVal = 0; 413 bool result = true;
414 414
415 if (ended) { 415 if (ended) {
416 // resend last packet in an event 3 times 416 // resend last packet in an event 3 times
417 sendCount = 3; 417 send_count = 3;
418 } 418 }
419 do { 419 do {
420 // Send DTMF data 420 // Send DTMF data
421 int32_t header_length = rtp_sender_->BuildRtpHeader( 421 int32_t header_length = rtp_sender_->BuildRtpHeader(
422 dtmfbuffer, dtmf_payload_type, marker_bit, dtmf_timestamp, 422 dtmfbuffer, dtmf_payload_type, marker_bit, dtmf_timestamp,
423 clock_->TimeInMilliseconds()); 423 clock_->TimeInMilliseconds());
424 if (header_length <= 0) 424 if (header_length <= 0)
425 return -1; 425 return false;
426 426
427 // reset CSRC and X bit 427 // reset CSRC and X bit
428 dtmfbuffer[0] &= 0xe0; 428 dtmfbuffer[0] &= 0xe0;
429 429
430 // Create DTMF data 430 // Create DTMF data
431 /* From RFC 2833: 431 /* From RFC 2833:
432 432
433 0 1 2 3 433 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 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
435 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 435 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
436 | event |E|R| volume | duration | 436 | event |E|R| volume | duration |
437 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 437 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
438 */ 438 */
439 // R bit always cleared 439 // R bit always cleared
440 uint8_t R = 0x00; 440 uint8_t R = 0x00;
441 uint8_t volume = dtmf_level_; 441 uint8_t volume = dtmf_level_;
442 442
443 // First packet un-ended 443 // First packet un-ended
444 uint8_t E = ended ? 0x80 : 0x00; 444 uint8_t E = ended ? 0x80 : 0x00;
445 445
446 // First byte is Event number, equals key number 446 // First byte is Event number, equals key number
447 dtmfbuffer[12] = dtmf_key_; 447 dtmfbuffer[12] = dtmf_key_;
448 dtmfbuffer[13] = E | R | volume; 448 dtmfbuffer[13] = E | R | volume;
449 ByteWriter<uint16_t>::WriteBigEndian(dtmfbuffer + 14, duration); 449 ByteWriter<uint16_t>::WriteBigEndian(dtmfbuffer + 14, duration);
450 450
451 TRACE_EVENT_INSTANT2( 451 TRACE_EVENT_INSTANT2(
452 TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "Audio::SendTelephoneEvent", 452 TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "Audio::SendTelephoneEvent",
453 "timestamp", dtmf_timestamp, "seqnum", rtp_sender_->SequenceNumber()); 453 "timestamp", dtmf_timestamp, "seqnum", rtp_sender_->SequenceNumber());
454 retVal = rtp_sender_->SendToNetwork(dtmfbuffer, 4, 12, rtc::TimeMillis(), 454 result = rtp_sender_->SendToNetwork(dtmfbuffer, 4, 12, rtc::TimeMillis(),
455 kAllowRetransmission, 455 kAllowRetransmission,
456 RtpPacketSender::kHighPriority); 456 RtpPacketSender::kHighPriority);
457 sendCount--; 457 send_count--;
458 } while (sendCount > 0 && retVal == 0); 458 } while (send_count > 0 && result);
459 459
460 return retVal; 460 return result;
461 } 461 }
462 } // namespace webrtc 462 } // 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