| 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);
|
|
|