Index: webrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc |
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc |
index 9b1b3bbc6d00ab7e1745e576022f06689bd0c8e8..c6223813a133a759b91e418c5be91ea54282bbc5 100644 |
--- a/webrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc |
+++ b/webrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc |
@@ -16,6 +16,8 @@ |
#include "webrtc/base/timeutils.h" |
#include "webrtc/base/trace_event.h" |
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" |
+#include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h" |
+#include "webrtc/modules/rtp_rtcp/source/rtp_packet_to_send.h" |
#include "webrtc/modules/rtp_rtcp/source/byte_io.h" |
namespace webrtc { |
@@ -153,7 +155,6 @@ bool RTPSenderAudio::SendAudio(FrameType frame_type, |
const RTPFragmentationHeader* fragmentation) { |
// TODO(pwestin) Breakup function in smaller functions. |
size_t payload_size = data_size; |
- size_t max_payload_length = rtp_sender_->MaxPayloadLength(); |
uint16_t dtmf_length_ms = 0; |
uint8_t key = 0; |
int red_payload_type; |
@@ -247,111 +248,46 @@ bool RTPSenderAudio::SendAudio(FrameType frame_type, |
} |
return false; |
} |
- uint8_t data_buffer[IP_PACKET_SIZE]; |
- bool marker_bit = MarkerBit(frame_type, payload_type); |
- |
- int32_t rtpHeaderLength = 0; |
- uint16_t timestampOffset = 0; |
- if (red_payload_type >= 0 && fragmentation && !marker_bit && |
- fragmentation->fragmentationVectorSize > 1) { |
- // have we configured RED? use its payload type |
- // we need to get the current timestamp to calc the diff |
- uint32_t old_timestamp = rtp_sender_->Timestamp(); |
- rtpHeaderLength = rtp_sender_->BuildRtpHeader(data_buffer, red_payload_type, |
- marker_bit, capture_timestamp, |
- clock_->TimeInMilliseconds()); |
- |
- timestampOffset = uint16_t(rtp_sender_->Timestamp() - old_timestamp); |
- } else { |
- rtpHeaderLength = rtp_sender_->BuildRtpHeader(data_buffer, payload_type, |
- marker_bit, capture_timestamp, |
- clock_->TimeInMilliseconds()); |
- } |
- if (rtpHeaderLength <= 0) { |
- return false; |
- } |
- if (max_payload_length < (rtpHeaderLength + payload_size)) { |
- // Too large payload buffer. |
+ std::unique_ptr<RtpPacketToSend> packet = rtp_sender_->AllocatePacket(false); |
+ if (!packet) |
return false; |
- } |
- if (red_payload_type >= 0 && // Have we configured RED? |
- fragmentation && fragmentation->fragmentationVectorSize > 1 && |
- !marker_bit) { |
- if (timestampOffset <= 0x3fff) { |
- if (fragmentation->fragmentationVectorSize != 2) { |
- // we only support 2 codecs when using RED |
- return false; |
- } |
- // only 0x80 if we have multiple blocks |
- data_buffer[rtpHeaderLength++] = |
- 0x80 + fragmentation->fragmentationPlType[1]; |
- size_t blockLength = fragmentation->fragmentationLength[1]; |
- |
- // sanity blockLength |
- if (blockLength > 0x3ff) { // block length 10 bits 1023 bytes |
- return false; |
- } |
- uint32_t REDheader = (timestampOffset << 10) + blockLength; |
- ByteWriter<uint32_t>::WriteBigEndian(data_buffer + rtpHeaderLength, |
- REDheader); |
- rtpHeaderLength += 3; |
- |
- data_buffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0]; |
- // copy the RED data |
- memcpy(data_buffer + rtpHeaderLength, |
- payload_data + fragmentation->fragmentationOffset[1], |
- fragmentation->fragmentationLength[1]); |
- |
- // copy the normal data |
- memcpy( |
- data_buffer + rtpHeaderLength + fragmentation->fragmentationLength[1], |
- payload_data + fragmentation->fragmentationOffset[0], |
- fragmentation->fragmentationLength[0]); |
- |
- payload_size = fragmentation->fragmentationLength[0] + |
- fragmentation->fragmentationLength[1]; |
- } else { |
- // silence for too long send only new data |
- data_buffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0]; |
- memcpy(data_buffer + rtpHeaderLength, |
- payload_data + fragmentation->fragmentationOffset[0], |
- fragmentation->fragmentationLength[0]); |
- |
- payload_size = fragmentation->fragmentationLength[0]; |
- } |
+ bool marker_bit = MarkerBit(frame_type, payload_type); |
+ packet->SetPayloadType(payload_type); |
+ packet->SetMarker(marker_bit); |
+ packet->SetTimestamp(capture_timestamp); |
+ packet->set_capture_time_ms(clock_->TimeInMilliseconds()); |
+ // Update audio level extension, if included. |
+ packet->SetExtension<AudioLevel>(frame_type == kAudioFrameSpeech, |
+ audio_level_dbov); |
+ |
+ if (fragmentation && fragmentation->fragmentationVectorSize > 0) { |
+ // use the fragment info if we have one |
+ uint8_t* payload = |
+ packet->AllocatePayload(1 + fragmentation->fragmentationLength[0]); |
+ if (!payload) |
+ return false; |
+ payload[0] = fragmentation->fragmentationPlType[0]; |
+ memcpy(payload + 1, payload_data + fragmentation->fragmentationOffset[0], |
+ fragmentation->fragmentationLength[0]); |
} else { |
- if (fragmentation && fragmentation->fragmentationVectorSize > 0) { |
- // use the fragment info if we have one |
- data_buffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0]; |
- memcpy(data_buffer + rtpHeaderLength, |
- payload_data + fragmentation->fragmentationOffset[0], |
- fragmentation->fragmentationLength[0]); |
- |
- payload_size = fragmentation->fragmentationLength[0]; |
- } else { |
- memcpy(data_buffer + rtpHeaderLength, payload_data, payload_size); |
- } |
+ uint8_t* payload = packet->AllocatePayload(payload_size); |
+ if (!payload) |
+ return false; |
+ memcpy(payload, payload_data, payload_size); |
} |
{ |
rtc::CritScope cs(&send_audio_critsect_); |
last_payload_type_ = payload_type; |
} |
- // Update audio level extension, if included. |
- size_t packetSize = payload_size + rtpHeaderLength; |
- RtpUtility::RtpHeaderParser rtp_parser(data_buffer, packetSize); |
- RTPHeader rtp_header; |
- rtp_parser.Parse(&rtp_header); |
- rtp_sender_->UpdateAudioLevel(data_buffer, packetSize, rtp_header, |
- (frame_type == kAudioFrameSpeech), |
- audio_level_dbov); |
+ // Allocate sequence number. |
+ rtp_sender_->PrepareToSend(packet.get()); |
TRACE_EVENT_ASYNC_END2("webrtc", "Audio", capture_timestamp, "timestamp", |
- rtp_sender_->Timestamp(), "seqnum", |
- rtp_sender_->SequenceNumber()); |
+ packet->Timestamp(), "seqnum", |
+ packet->SequenceNumber()); |
bool send_result = rtp_sender_->SendToNetwork( |
- data_buffer, payload_size, rtpHeaderLength, rtc::TimeMillis(), |
- kAllowRetransmission, RtpPacketSender::kHighPriority); |
+ std::move(packet), kAllowRetransmission, RtpPacketSender::kHighPriority); |
if (first_packet_sent_()) { |
LOG(LS_INFO) << "First audio RTP packet sent to pacer"; |
} |
@@ -408,7 +344,6 @@ bool RTPSenderAudio::SendTelephoneEventPacket(bool ended, |
uint32_t dtmf_timestamp, |
uint16_t duration, |
bool marker_bit) { |
- uint8_t dtmfbuffer[IP_PACKET_SIZE]; |
uint8_t send_count = 1; |
bool result = true; |
@@ -418,14 +353,13 @@ bool RTPSenderAudio::SendTelephoneEventPacket(bool ended, |
} |
do { |
// Send DTMF data |
- int32_t header_length = rtp_sender_->BuildRtpHeader( |
- dtmfbuffer, dtmf_payload_type, marker_bit, dtmf_timestamp, |
- clock_->TimeInMilliseconds()); |
- if (header_length <= 0) |
+ std::unique_ptr<RtpPacketToSend> packet = rtp_sender_->AllocatePacket(true); |
+ if (!packet) |
return false; |
- |
- // reset CSRC and X bit |
- dtmfbuffer[0] &= 0xe0; |
+ packet->SetPayloadType(dtmf_payload_type); |
+ packet->SetMarker(marker_bit); |
+ packet->SetTimestamp(dtmf_timestamp); |
+ packet->set_capture_time_ms(clock_->TimeInMilliseconds()); |
// Create DTMF data |
/* From RFC 2833: |
@@ -443,16 +377,19 @@ bool RTPSenderAudio::SendTelephoneEventPacket(bool ended, |
// First packet un-ended |
uint8_t E = ended ? 0x80 : 0x00; |
+ uint8_t* dtmfbuffer = packet->AllocatePayload(4); |
+ RTC_DCHECK(dtmfbuffer); |
// First byte is Event number, equals key number |
- dtmfbuffer[12] = dtmf_key_; |
- dtmfbuffer[13] = E | R | volume; |
- ByteWriter<uint16_t>::WriteBigEndian(dtmfbuffer + 14, duration); |
- |
- TRACE_EVENT_INSTANT2( |
- TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "Audio::SendTelephoneEvent", |
- "timestamp", dtmf_timestamp, "seqnum", rtp_sender_->SequenceNumber()); |
- result = rtp_sender_->SendToNetwork(dtmfbuffer, 4, 12, rtc::TimeMillis(), |
- kAllowRetransmission, |
+ dtmfbuffer[0] = dtmf_key_; |
+ dtmfbuffer[1] = E | R | volume; |
+ ByteWriter<uint16_t>::WriteBigEndian(dtmfbuffer + 2, duration); |
+ if (!rtp_sender_->PrepareToSend(packet.get())) |
+ return false; |
+ |
+ TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), |
+ "Audio::SendTelephoneEvent", "timestamp", |
+ dtmf_timestamp, "seqnum", packet->SequenceNumber()); |
+ result = rtp_sender_->SendToNetwork(std::move(packet), kAllowRetransmission, |
RtpPacketSender::kHighPriority); |
send_count--; |
} while (send_count > 0 && result); |