Line data Source code
1 : /*
2 : * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 : *
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
6 : * tree. An additional intellectual property rights grant can be found
7 : * in the file PATENTS. All contributing project authors may
8 : * be found in the AUTHORS file in the root of the source tree.
9 : */
10 :
11 : #include "webrtc/modules/rtp_rtcp/source/rtp_sender_audio.h"
12 :
13 : #include <string.h>
14 :
15 : #include <memory>
16 : #include <utility>
17 :
18 : #include "webrtc/base/logging.h"
19 : #include "webrtc/base/timeutils.h"
20 : #include "webrtc/base/trace_event.h"
21 : #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.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"
25 :
26 : namespace webrtc {
27 :
28 0 : RTPSenderAudio::RTPSenderAudio(Clock* clock, RTPSender* rtp_sender)
29 : : clock_(clock),
30 0 : rtp_sender_(rtp_sender) {}
31 :
32 0 : RTPSenderAudio::~RTPSenderAudio() {}
33 :
34 0 : int32_t RTPSenderAudio::RegisterAudioPayload(
35 : const char payloadName[RTP_PAYLOAD_NAME_SIZE],
36 : const int8_t payload_type,
37 : const uint32_t frequency,
38 : const size_t channels,
39 : const uint32_t rate,
40 : RtpUtility::Payload** payload) {
41 0 : if (RtpUtility::StringCompare(payloadName, "cn", 2)) {
42 0 : rtc::CritScope cs(&send_audio_critsect_);
43 : // we can have multiple CNG payload types
44 0 : switch (frequency) {
45 : case 8000:
46 0 : cngnb_payload_type_ = payload_type;
47 0 : break;
48 : case 16000:
49 0 : cngwb_payload_type_ = payload_type;
50 0 : break;
51 : case 32000:
52 0 : cngswb_payload_type_ = payload_type;
53 0 : break;
54 : case 48000:
55 0 : cngfb_payload_type_ = payload_type;
56 0 : break;
57 : default:
58 0 : return -1;
59 : }
60 0 : } else if (RtpUtility::StringCompare(payloadName, "telephone-event", 15)) {
61 0 : rtc::CritScope cs(&send_audio_critsect_);
62 : // Don't add it to the list
63 : // we dont want to allow send with a DTMF payloadtype
64 0 : dtmf_payload_type_ = payload_type;
65 0 : dtmf_payload_freq_ = frequency;
66 0 : return 0;
67 : }
68 0 : *payload = new RtpUtility::Payload;
69 0 : (*payload)->typeSpecific.Audio.frequency = frequency;
70 0 : (*payload)->typeSpecific.Audio.channels = channels;
71 0 : (*payload)->typeSpecific.Audio.rate = rate;
72 0 : (*payload)->audio = true;
73 0 : (*payload)->name[RTP_PAYLOAD_NAME_SIZE - 1] = '\0';
74 0 : strncpy((*payload)->name, payloadName, RTP_PAYLOAD_NAME_SIZE - 1);
75 0 : return 0;
76 : }
77 :
78 0 : bool RTPSenderAudio::MarkerBit(FrameType frame_type, int8_t payload_type) {
79 0 : rtc::CritScope cs(&send_audio_critsect_);
80 : // for audio true for first packet in a speech burst
81 0 : bool marker_bit = false;
82 0 : if (last_payload_type_ != payload_type) {
83 0 : if (payload_type != -1 && (cngnb_payload_type_ == payload_type ||
84 0 : cngwb_payload_type_ == payload_type ||
85 0 : cngswb_payload_type_ == payload_type ||
86 0 : cngfb_payload_type_ == payload_type)) {
87 : // Only set a marker bit when we change payload type to a non CNG
88 0 : return false;
89 : }
90 :
91 : // payload_type differ
92 0 : if (last_payload_type_ == -1) {
93 0 : if (frame_type != kAudioFrameCN) {
94 : // first packet and NOT CNG
95 0 : return true;
96 : } else {
97 : // first packet and CNG
98 0 : inband_vad_active_ = true;
99 0 : return false;
100 : }
101 : }
102 :
103 : // not first packet AND
104 : // not CNG AND
105 : // payload_type changed
106 :
107 : // set a marker bit when we change payload type
108 0 : marker_bit = true;
109 : }
110 :
111 : // For G.723 G.729, AMR etc we can have inband VAD
112 0 : if (frame_type == kAudioFrameCN) {
113 0 : inband_vad_active_ = true;
114 0 : } else if (inband_vad_active_) {
115 0 : inband_vad_active_ = false;
116 0 : marker_bit = true;
117 : }
118 0 : return marker_bit;
119 : }
120 :
121 0 : bool RTPSenderAudio::SendAudio(FrameType frame_type,
122 : int8_t payload_type,
123 : uint32_t rtp_timestamp,
124 : const uint8_t* payload_data,
125 : size_t payload_size,
126 : const RTPFragmentationHeader* fragmentation) {
127 : // From RFC 4733:
128 : // A source has wide latitude as to how often it sends event updates. A
129 : // natural interval is the spacing between non-event audio packets. [...]
130 : // Alternatively, a source MAY decide to use a different spacing for event
131 : // updates, with a value of 50 ms RECOMMENDED.
132 0 : constexpr int kDtmfIntervalTimeMs = 50;
133 0 : uint8_t audio_level_dbov = 0;
134 0 : uint32_t dtmf_payload_freq = 0;
135 : {
136 0 : rtc::CritScope cs(&send_audio_critsect_);
137 0 : audio_level_dbov = audio_level_dbov_;
138 0 : dtmf_payload_freq = dtmf_payload_freq_;
139 : }
140 :
141 : // Check if we have pending DTMFs to send
142 0 : if (!dtmf_event_is_on_ && dtmf_queue_.PendingDtmf()) {
143 0 : if ((clock_->TimeInMilliseconds() - dtmf_time_last_sent_) >
144 : kDtmfIntervalTimeMs) {
145 : // New tone to play
146 0 : dtmf_timestamp_ = rtp_timestamp;
147 0 : if (dtmf_queue_.NextDtmf(&dtmf_current_event_)) {
148 0 : dtmf_event_first_packet_sent_ = false;
149 0 : dtmf_length_samples_ =
150 0 : dtmf_current_event_.duration_ms * (dtmf_payload_freq / 1000);
151 0 : dtmf_event_is_on_ = true;
152 : }
153 : }
154 : }
155 :
156 : // A source MAY send events and coded audio packets for the same time
157 : // but we don't support it
158 0 : if (dtmf_event_is_on_) {
159 0 : if (frame_type == kEmptyFrame) {
160 : // kEmptyFrame is used to drive the DTMF when in CN mode
161 : // it can be triggered more frequently than we want to send the
162 : // DTMF packets.
163 : const unsigned int dtmf_interval_time_rtp =
164 0 : dtmf_payload_freq * kDtmfIntervalTimeMs / 1000;
165 0 : if ((rtp_timestamp - dtmf_timestamp_last_sent_) <
166 : dtmf_interval_time_rtp) {
167 : // not time to send yet
168 0 : return true;
169 : }
170 : }
171 0 : dtmf_timestamp_last_sent_ = rtp_timestamp;
172 0 : uint32_t dtmf_duration_samples = rtp_timestamp - dtmf_timestamp_;
173 0 : bool ended = false;
174 0 : bool send = true;
175 :
176 0 : if (dtmf_length_samples_ > dtmf_duration_samples) {
177 0 : if (dtmf_duration_samples <= 0) {
178 : // Skip send packet at start, since we shouldn't use duration 0
179 0 : send = false;
180 : }
181 : } else {
182 0 : ended = true;
183 0 : dtmf_event_is_on_ = false;
184 0 : dtmf_time_last_sent_ = clock_->TimeInMilliseconds();
185 : }
186 0 : if (send) {
187 0 : if (dtmf_duration_samples > 0xffff) {
188 : // RFC 4733 2.5.2.3 Long-Duration Events
189 0 : SendTelephoneEventPacket(ended, dtmf_timestamp_,
190 0 : static_cast<uint16_t>(0xffff), false);
191 :
192 : // set new timestap for this segment
193 0 : dtmf_timestamp_ = rtp_timestamp;
194 0 : dtmf_duration_samples -= 0xffff;
195 0 : dtmf_length_samples_ -= 0xffff;
196 :
197 0 : return SendTelephoneEventPacket(ended, dtmf_timestamp_,
198 0 : static_cast<uint16_t>(dtmf_duration_samples), false);
199 : } else {
200 0 : if (!SendTelephoneEventPacket(ended, dtmf_timestamp_,
201 : dtmf_duration_samples,
202 0 : !dtmf_event_first_packet_sent_)) {
203 0 : return false;
204 : }
205 0 : dtmf_event_first_packet_sent_ = true;
206 0 : return true;
207 : }
208 : }
209 0 : return true;
210 : }
211 0 : if (payload_size == 0 || payload_data == NULL) {
212 0 : if (frame_type == kEmptyFrame) {
213 : // we don't send empty audio RTP packets
214 : // no error since we use it to drive DTMF when we use VAD
215 0 : return true;
216 : }
217 0 : return false;
218 : }
219 :
220 0 : std::unique_ptr<RtpPacketToSend> packet = rtp_sender_->AllocatePacket();
221 0 : packet->SetMarker(MarkerBit(frame_type, payload_type));
222 0 : packet->SetPayloadType(payload_type);
223 0 : packet->SetTimestamp(rtp_timestamp);
224 0 : packet->set_capture_time_ms(clock_->TimeInMilliseconds());
225 : // Update audio level extension, if included.
226 0 : packet->SetExtension<AudioLevel>(frame_type == kAudioFrameSpeech,
227 0 : audio_level_dbov);
228 :
229 0 : if (fragmentation && fragmentation->fragmentationVectorSize > 0) {
230 : // Use the fragment info if we have one.
231 : uint8_t* payload =
232 0 : packet->AllocatePayload(1 + fragmentation->fragmentationLength[0]);
233 0 : if (!payload) // Too large payload buffer.
234 0 : return false;
235 0 : payload[0] = fragmentation->fragmentationPlType[0];
236 0 : memcpy(payload + 1, payload_data + fragmentation->fragmentationOffset[0],
237 0 : fragmentation->fragmentationLength[0]);
238 : } else {
239 0 : uint8_t* payload = packet->AllocatePayload(payload_size);
240 0 : if (!payload) // Too large payload buffer.
241 0 : return false;
242 0 : memcpy(payload, payload_data, payload_size);
243 : }
244 :
245 0 : if (!rtp_sender_->AssignSequenceNumber(packet.get()))
246 0 : return false;
247 :
248 : {
249 0 : rtc::CritScope cs(&send_audio_critsect_);
250 0 : last_payload_type_ = payload_type;
251 : }
252 0 : TRACE_EVENT_ASYNC_END2("webrtc", "Audio", rtp_timestamp, "timestamp",
253 : packet->Timestamp(), "seqnum",
254 : packet->SequenceNumber());
255 0 : bool send_result = rtp_sender_->SendToNetwork(
256 0 : std::move(packet), kAllowRetransmission, RtpPacketSender::kHighPriority);
257 0 : if (first_packet_sent_()) {
258 0 : LOG(LS_INFO) << "First audio RTP packet sent to pacer";
259 : }
260 0 : return send_result;
261 : }
262 :
263 : // Audio level magnitude and voice activity flag are set for each RTP packet
264 0 : int32_t RTPSenderAudio::SetAudioLevel(uint8_t level_dbov) {
265 0 : if (level_dbov > 127) {
266 0 : return -1;
267 : }
268 0 : rtc::CritScope cs(&send_audio_critsect_);
269 0 : audio_level_dbov_ = level_dbov;
270 0 : return 0;
271 : }
272 :
273 : // Send a TelephoneEvent tone using RFC 2833 (4733)
274 0 : int32_t RTPSenderAudio::SendTelephoneEvent(uint8_t key,
275 : uint16_t time_ms,
276 : uint8_t level) {
277 0 : DtmfQueue::Event event;
278 : {
279 0 : rtc::CritScope lock(&send_audio_critsect_);
280 0 : if (dtmf_payload_type_ < 0) {
281 : // TelephoneEvent payloadtype not configured
282 0 : return -1;
283 : }
284 0 : event.payload_type = dtmf_payload_type_;
285 : }
286 0 : event.key = key;
287 0 : event.duration_ms = time_ms;
288 0 : event.level = level;
289 0 : return dtmf_queue_.AddDtmf(event) ? 0 : -1;
290 : }
291 :
292 0 : bool RTPSenderAudio::SendTelephoneEventPacket(bool ended,
293 : uint32_t dtmf_timestamp,
294 : uint16_t duration,
295 : bool marker_bit) {
296 0 : uint8_t send_count = 1;
297 0 : bool result = true;
298 :
299 0 : if (ended) {
300 : // resend last packet in an event 3 times
301 0 : send_count = 3;
302 : }
303 0 : do {
304 : // Send DTMF data.
305 0 : constexpr RtpPacketToSend::ExtensionManager* kNoExtensions = nullptr;
306 0 : constexpr size_t kDtmfSize = 4;
307 : std::unique_ptr<RtpPacketToSend> packet(
308 0 : new RtpPacketToSend(kNoExtensions, kRtpHeaderSize + kDtmfSize));
309 0 : packet->SetPayloadType(dtmf_current_event_.payload_type);
310 0 : packet->SetMarker(marker_bit);
311 0 : packet->SetSsrc(rtp_sender_->SSRC());
312 0 : packet->SetTimestamp(dtmf_timestamp);
313 0 : packet->set_capture_time_ms(clock_->TimeInMilliseconds());
314 0 : if (!rtp_sender_->AssignSequenceNumber(packet.get()))
315 0 : return false;
316 :
317 : // Create DTMF data.
318 0 : uint8_t* dtmfbuffer = packet->AllocatePayload(kDtmfSize);
319 0 : RTC_DCHECK(dtmfbuffer);
320 : /* From RFC 2833:
321 : 0 1 2 3
322 : 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
323 : +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
324 : | event |E|R| volume | duration |
325 : +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
326 : */
327 : // R bit always cleared
328 0 : uint8_t R = 0x00;
329 0 : uint8_t volume = dtmf_current_event_.level;
330 :
331 : // First packet un-ended
332 0 : uint8_t E = ended ? 0x80 : 0x00;
333 :
334 : // First byte is Event number, equals key number
335 0 : dtmfbuffer[0] = dtmf_current_event_.key;
336 0 : dtmfbuffer[1] = E | R | volume;
337 0 : ByteWriter<uint16_t>::WriteBigEndian(dtmfbuffer + 2, duration);
338 :
339 0 : TRACE_EVENT_INSTANT2(
340 : TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "Audio::SendTelephoneEvent",
341 : "timestamp", packet->Timestamp(), "seqnum", packet->SequenceNumber());
342 0 : result = rtp_sender_->SendToNetwork(std::move(packet), kAllowRetransmission,
343 0 : RtpPacketSender::kHighPriority);
344 0 : send_count--;
345 0 : } while (send_count > 0 && result);
346 :
347 0 : return result;
348 : }
349 : } // namespace webrtc
|