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_receiver_audio.h" | 11 #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_audio.h" |
12 | 12 |
13 #include <assert.h> // assert | 13 #include <assert.h> // assert |
14 #include <math.h> // pow() | 14 #include <math.h> // pow() |
15 #include <string.h> // memcpy() | 15 #include <string.h> // memcpy() |
16 | 16 |
17 #include "webrtc/base/logging.h" | 17 #include "webrtc/base/logging.h" |
18 #include "webrtc/base/trace_event.h" | 18 #include "webrtc/base/trace_event.h" |
19 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" | |
20 | 19 |
21 namespace webrtc { | 20 namespace webrtc { |
22 RTPReceiverStrategy* RTPReceiverStrategy::CreateAudioStrategy( | 21 RTPReceiverStrategy* RTPReceiverStrategy::CreateAudioStrategy( |
23 RtpData* data_callback) { | 22 RtpData* data_callback) { |
24 return new RTPReceiverAudio(data_callback); | 23 return new RTPReceiverAudio(data_callback); |
25 } | 24 } |
26 | 25 |
27 RTPReceiverAudio::RTPReceiverAudio(RtpData* data_callback) | 26 RTPReceiverAudio::RTPReceiverAudio(RtpData* data_callback) |
28 : RTPReceiverStrategy(data_callback), | 27 : RTPReceiverStrategy(data_callback), |
29 TelephoneEventHandler(), | 28 TelephoneEventHandler(), |
30 last_received_frequency_(8000), | 29 last_received_frequency_(8000), |
31 telephone_event_forward_to_decoder_(false), | 30 telephone_event_forward_to_decoder_(false), |
32 telephone_event_payload_type_(-1), | 31 telephone_event_payload_type_(-1), |
33 cng_nb_payload_type_(-1), | 32 cng_nb_payload_type_(-1), |
34 cng_wb_payload_type_(-1), | 33 cng_wb_payload_type_(-1), |
35 cng_swb_payload_type_(-1), | 34 cng_swb_payload_type_(-1), |
36 cng_fb_payload_type_(-1), | 35 cng_fb_payload_type_(-1), |
37 cng_payload_type_(-1), | 36 cng_payload_type_(-1), |
38 g722_payload_type_(-1), | 37 g722_payload_type_(-1), |
39 last_received_g722_(false), | 38 last_received_g722_(false), |
40 num_energy_(0), | 39 num_energy_(0), |
41 current_remote_energy_() { | 40 current_remote_energy_() { |
42 last_payload_.Audio.channels = 1; | 41 last_payload_.Audio.channels = 1; |
43 memset(current_remote_energy_, 0, sizeof(current_remote_energy_)); | 42 memset(current_remote_energy_, 0, sizeof(current_remote_energy_)); |
44 } | 43 } |
45 | 44 |
46 // Outband TelephoneEvent(DTMF) detection | 45 // Outband TelephoneEvent(DTMF) detection |
47 void RTPReceiverAudio::SetTelephoneEventForwardToDecoder( | 46 void RTPReceiverAudio::SetTelephoneEventForwardToDecoder( |
48 bool forward_to_decoder) { | 47 bool forward_to_decoder) { |
49 CriticalSectionScoped lock(crit_sect_.get()); | 48 rtc::CritScope lock(&crit_sect_); |
50 telephone_event_forward_to_decoder_ = forward_to_decoder; | 49 telephone_event_forward_to_decoder_ = forward_to_decoder; |
51 } | 50 } |
52 | 51 |
53 // Is forwarding of outband telephone events turned on/off? | 52 // Is forwarding of outband telephone events turned on/off? |
54 bool RTPReceiverAudio::TelephoneEventForwardToDecoder() const { | 53 bool RTPReceiverAudio::TelephoneEventForwardToDecoder() const { |
55 CriticalSectionScoped lock(crit_sect_.get()); | 54 rtc::CritScope lock(&crit_sect_); |
56 return telephone_event_forward_to_decoder_; | 55 return telephone_event_forward_to_decoder_; |
57 } | 56 } |
58 | 57 |
59 bool RTPReceiverAudio::TelephoneEventPayloadType( | 58 bool RTPReceiverAudio::TelephoneEventPayloadType( |
60 int8_t payload_type) const { | 59 int8_t payload_type) const { |
61 CriticalSectionScoped lock(crit_sect_.get()); | 60 rtc::CritScope lock(&crit_sect_); |
62 return telephone_event_payload_type_ == payload_type; | 61 return telephone_event_payload_type_ == payload_type; |
63 } | 62 } |
64 | 63 |
65 bool RTPReceiverAudio::CNGPayloadType(int8_t payload_type, | 64 bool RTPReceiverAudio::CNGPayloadType(int8_t payload_type, |
66 uint32_t* frequency, | 65 uint32_t* frequency, |
67 bool* cng_payload_type_has_changed) { | 66 bool* cng_payload_type_has_changed) { |
68 CriticalSectionScoped lock(crit_sect_.get()); | 67 rtc::CritScope lock(&crit_sect_); |
69 *cng_payload_type_has_changed = false; | 68 *cng_payload_type_has_changed = false; |
70 | 69 |
71 // We can have four CNG on 8000Hz, 16000Hz, 32000Hz and 48000Hz. | 70 // We can have four CNG on 8000Hz, 16000Hz, 32000Hz and 48000Hz. |
72 if (cng_nb_payload_type_ == payload_type) { | 71 if (cng_nb_payload_type_ == payload_type) { |
73 *frequency = 8000; | 72 *frequency = 8000; |
74 if (cng_payload_type_ != -1 && cng_payload_type_ != cng_nb_payload_type_) | 73 if (cng_payload_type_ != -1 && cng_payload_type_ != cng_nb_payload_type_) |
75 *cng_payload_type_has_changed = true; | 74 *cng_payload_type_has_changed = true; |
76 | 75 |
77 cng_payload_type_ = cng_nb_payload_type_; | 76 cng_payload_type_ = cng_nb_payload_type_; |
78 return true; | 77 return true; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 // - GSM frame N/A 8,000 20 20 | 144 // - GSM frame N/A 8,000 20 20 |
146 // - GSM-EFR frame N/A 8,000 20 20 | 145 // - GSM-EFR frame N/A 8,000 20 20 |
147 // - LPC frame N/A 8,000 20 20 | 146 // - LPC frame N/A 8,000 20 20 |
148 // - MPA frame N/A var. var. | 147 // - MPA frame N/A var. var. |
149 // - | 148 // - |
150 // - G7221 frame N/A | 149 // - G7221 frame N/A |
151 int32_t RTPReceiverAudio::OnNewPayloadTypeCreated( | 150 int32_t RTPReceiverAudio::OnNewPayloadTypeCreated( |
152 const char payload_name[RTP_PAYLOAD_NAME_SIZE], | 151 const char payload_name[RTP_PAYLOAD_NAME_SIZE], |
153 int8_t payload_type, | 152 int8_t payload_type, |
154 uint32_t frequency) { | 153 uint32_t frequency) { |
155 CriticalSectionScoped lock(crit_sect_.get()); | 154 rtc::CritScope lock(&crit_sect_); |
156 | 155 |
157 if (RtpUtility::StringCompare(payload_name, "telephone-event", 15)) { | 156 if (RtpUtility::StringCompare(payload_name, "telephone-event", 15)) { |
158 telephone_event_payload_type_ = payload_type; | 157 telephone_event_payload_type_ = payload_type; |
159 } | 158 } |
160 if (RtpUtility::StringCompare(payload_name, "cn", 2)) { | 159 if (RtpUtility::StringCompare(payload_name, "cn", 2)) { |
161 // we can have three CNG on 8000Hz, 16000Hz and 32000Hz | 160 // we can have three CNG on 8000Hz, 16000Hz and 32000Hz |
162 if (frequency == 8000) { | 161 if (frequency == 8000) { |
163 cng_nb_payload_type_ = payload_type; | 162 cng_nb_payload_type_ = payload_type; |
164 } else if (frequency == 16000) { | 163 } else if (frequency == 16000) { |
165 cng_wb_payload_type_ = payload_type; | 164 cng_wb_payload_type_ = payload_type; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 } | 198 } |
200 | 199 |
201 return ParseAudioCodecSpecific(rtp_header, | 200 return ParseAudioCodecSpecific(rtp_header, |
202 payload, | 201 payload, |
203 payload_length, | 202 payload_length, |
204 specific_payload.Audio, | 203 specific_payload.Audio, |
205 is_red); | 204 is_red); |
206 } | 205 } |
207 | 206 |
208 int RTPReceiverAudio::GetPayloadTypeFrequency() const { | 207 int RTPReceiverAudio::GetPayloadTypeFrequency() const { |
209 CriticalSectionScoped lock(crit_sect_.get()); | 208 rtc::CritScope lock(&crit_sect_); |
210 if (last_received_g722_) { | 209 if (last_received_g722_) { |
211 return 8000; | 210 return 8000; |
212 } | 211 } |
213 return last_received_frequency_; | 212 return last_received_frequency_; |
214 } | 213 } |
215 | 214 |
216 RTPAliveType RTPReceiverAudio::ProcessDeadOrAlive( | 215 RTPAliveType RTPReceiverAudio::ProcessDeadOrAlive( |
217 uint16_t last_payload_length) const { | 216 uint16_t last_payload_length) const { |
218 | 217 |
219 // Our CNG is 9 bytes; if it's a likely CNG the receiver needs to check | 218 // Our CNG is 9 bytes; if it's a likely CNG the receiver needs to check |
(...skipping 22 matching lines...) Expand all Loading... |
242 &cng_payload_type_has_changed); | 241 &cng_payload_type_has_changed); |
243 | 242 |
244 if (is_cng_payload_type) { | 243 if (is_cng_payload_type) { |
245 // Don't do callbacks for DTMF packets. | 244 // Don't do callbacks for DTMF packets. |
246 *should_discard_changes = true; | 245 *should_discard_changes = true; |
247 return; | 246 return; |
248 } | 247 } |
249 } | 248 } |
250 | 249 |
251 int RTPReceiverAudio::Energy(uint8_t array_of_energy[kRtpCsrcSize]) const { | 250 int RTPReceiverAudio::Energy(uint8_t array_of_energy[kRtpCsrcSize]) const { |
252 CriticalSectionScoped cs(crit_sect_.get()); | 251 rtc::CritScope cs(&crit_sect_); |
253 | 252 |
254 assert(num_energy_ <= kRtpCsrcSize); | 253 assert(num_energy_ <= kRtpCsrcSize); |
255 | 254 |
256 if (num_energy_ > 0) { | 255 if (num_energy_ > 0) { |
257 memcpy(array_of_energy, current_remote_energy_, | 256 memcpy(array_of_energy, current_remote_energy_, |
258 sizeof(uint8_t) * num_energy_); | 257 sizeof(uint8_t) * num_energy_); |
259 } | 258 } |
260 return num_energy_; | 259 return num_energy_; |
261 } | 260 } |
262 | 261 |
(...skipping 21 matching lines...) Expand all Loading... |
284 const AudioPayload& audio_specific, | 283 const AudioPayload& audio_specific, |
285 bool is_red) { | 284 bool is_red) { |
286 | 285 |
287 if (payload_length == 0) { | 286 if (payload_length == 0) { |
288 return 0; | 287 return 0; |
289 } | 288 } |
290 | 289 |
291 bool telephone_event_packet = | 290 bool telephone_event_packet = |
292 TelephoneEventPayloadType(rtp_header->header.payloadType); | 291 TelephoneEventPayloadType(rtp_header->header.payloadType); |
293 if (telephone_event_packet) { | 292 if (telephone_event_packet) { |
294 CriticalSectionScoped lock(crit_sect_.get()); | 293 rtc::CritScope lock(&crit_sect_); |
295 | 294 |
296 // RFC 4733 2.3 | 295 // RFC 4733 2.3 |
297 // 0 1 2 3 | 296 // 0 1 2 3 |
298 // 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 | 297 // 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 |
299 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 298 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
300 // | event |E|R| volume | duration | | 299 // | event |E|R| volume | duration | |
301 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 300 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
302 // | 301 // |
303 if (payload_length % 4 != 0) { | 302 if (payload_length % 4 != 0) { |
304 return -1; | 303 return -1; |
(...skipping 24 matching lines...) Expand all Loading... |
329 } | 328 } |
330 } | 329 } |
331 | 330 |
332 // RFC 4733 2.5.1.3 & 2.5.2.3 Long-Duration Events | 331 // RFC 4733 2.5.1.3 & 2.5.2.3 Long-Duration Events |
333 // should not be a problem since we don't care about the duration | 332 // should not be a problem since we don't care about the duration |
334 | 333 |
335 // RFC 4733 See 2.5.1.5. & 2.5.2.4. Multiple Events in a Packet | 334 // RFC 4733 See 2.5.1.5. & 2.5.2.4. Multiple Events in a Packet |
336 } | 335 } |
337 | 336 |
338 { | 337 { |
339 CriticalSectionScoped lock(crit_sect_.get()); | 338 rtc::CritScope lock(&crit_sect_); |
340 | 339 |
341 if (!telephone_event_packet) { | 340 if (!telephone_event_packet) { |
342 last_received_frequency_ = audio_specific.frequency; | 341 last_received_frequency_ = audio_specific.frequency; |
343 } | 342 } |
344 | 343 |
345 // Check if this is a CNG packet, receiver might want to know | 344 // Check if this is a CNG packet, receiver might want to know |
346 uint32_t ignored; | 345 uint32_t ignored; |
347 bool also_ignored; | 346 bool also_ignored; |
348 if (CNGPayloadType(rtp_header->header.payloadType, | 347 if (CNGPayloadType(rtp_header->header.payloadType, |
349 &ignored, | 348 &ignored, |
(...skipping 27 matching lines...) Expand all Loading... |
377 // only one frame in the RED strip the one byte to help NetEq | 376 // only one frame in the RED strip the one byte to help NetEq |
378 return data_callback_->OnReceivedPayloadData( | 377 return data_callback_->OnReceivedPayloadData( |
379 payload_data + 1, payload_length - 1, rtp_header); | 378 payload_data + 1, payload_length - 1, rtp_header); |
380 } | 379 } |
381 | 380 |
382 rtp_header->type.Audio.channel = audio_specific.channels; | 381 rtp_header->type.Audio.channel = audio_specific.channels; |
383 return data_callback_->OnReceivedPayloadData( | 382 return data_callback_->OnReceivedPayloadData( |
384 payload_data, payload_length, rtp_header); | 383 payload_data, payload_length, rtp_header); |
385 } | 384 } |
386 } // namespace webrtc | 385 } // namespace webrtc |
OLD | NEW |