1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Use of this source code is governed by a BSD-style license 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * that can be found in the LICENSE file in the root of the source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * tree. An additional intellectual property rights grant can be found 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in the file PATENTS. All contributing project authors may 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 11eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_audio.h" 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 133f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <assert.h> // assert 14eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org#include <math.h> // pow() 153f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <string.h> // memcpy() 16eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org 17eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 1899681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org#include "webrtc/system_wrappers/interface/logging.h" 19dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com#include "webrtc/system_wrappers/interface/trace_event.h" 20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc { 227fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.orgRTPReceiverStrategy* RTPReceiverStrategy::CreateAudioStrategy( 237fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org int32_t id, RtpData* data_callback, 247fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org RtpAudioFeedback* incoming_messages_callback) { 257fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org return new RTPReceiverAudio(id, data_callback, incoming_messages_callback); 267fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org} 277fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org 28b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgRTPReceiverAudio::RTPReceiverAudio(const int32_t id, 29cd29867e6b49df11e565dcb1d64dbe92751b509cphoglund@webrtc.org RtpData* data_callback, 30eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org RtpAudioFeedback* incoming_messages_callback) 31eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org : RTPReceiverStrategy(data_callback), 327fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org TelephoneEventHandler(), 33eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org id_(id), 34eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org last_received_frequency_(8000), 35eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org telephone_event_forward_to_decoder_(false), 36eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org telephone_event_payload_type_(-1), 37eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org cng_nb_payload_type_(-1), 38eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org cng_wb_payload_type_(-1), 39eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org cng_swb_payload_type_(-1), 40eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org cng_fb_payload_type_(-1), 41eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org cng_payload_type_(-1), 42eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org g722_payload_type_(-1), 43eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org last_received_g722_(false), 447fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org num_energy_(0), 457fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org current_remote_energy_(), 46eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org cb_audio_feedback_(incoming_messages_callback) { 477d91c10c601030978979529a17edbc51784866cephoglund@webrtc.org last_payload_.Audio.channels = 1; 487fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org memset(current_remote_energy_, 0, sizeof(current_remote_energy_)); 49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Outband TelephoneEvent(DTMF) detection 527fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.orgvoid RTPReceiverAudio::SetTelephoneEventForwardToDecoder( 5315a03fd972746f234e2dd9bb5540ae0b4ad6ee82turaj@webrtc.org bool forward_to_decoder) { 547fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org CriticalSectionScoped lock(crit_sect_.get()); 55eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org telephone_event_forward_to_decoder_ = forward_to_decoder; 56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Is forwarding of outband telephone events turned on/off? 59eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.orgbool RTPReceiverAudio::TelephoneEventForwardToDecoder() const { 607fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org CriticalSectionScoped lock(crit_sect_.get()); 61eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org return telephone_event_forward_to_decoder_; 62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 64eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.orgbool RTPReceiverAudio::TelephoneEventPayloadType( 657fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org int8_t payload_type) const { 667fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org CriticalSectionScoped lock(crit_sect_.get()); 67eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org return (telephone_event_payload_type_ == payload_type) ? true : false; 68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 707fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.orgbool RTPReceiverAudio::CNGPayloadType(int8_t payload_type, 71b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint32_t* frequency, 72eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org bool* cng_payload_type_has_changed) { 737fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org CriticalSectionScoped lock(crit_sect_.get()); 74eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org *cng_payload_type_has_changed = false; 75eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org 76eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org // We can have four CNG on 8000Hz, 16000Hz, 32000Hz and 48000Hz. 77eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org if (cng_nb_payload_type_ == payload_type) { 78eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org *frequency = 8000; 79eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org if (cng_payload_type_ != -1 && cng_payload_type_ != cng_nb_payload_type_) 80eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org *cng_payload_type_has_changed = true; 81eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org 82eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org cng_payload_type_ = cng_nb_payload_type_; 83eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org return true; 84eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org } else if (cng_wb_payload_type_ == payload_type) { 85eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org // if last received codec is G.722 we must use frequency 8000 86eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org if (last_received_g722_) { 87eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org *frequency = 8000; 88eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org } else { 89eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org *frequency = 16000; 90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 91eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org if (cng_payload_type_ != -1 && cng_payload_type_ != cng_wb_payload_type_) 92eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org *cng_payload_type_has_changed = true; 93eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org cng_payload_type_ = cng_wb_payload_type_; 94eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org return true; 95eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org } else if (cng_swb_payload_type_ == payload_type) { 96eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org *frequency = 32000; 97eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org if ((cng_payload_type_ != -1) && 98eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org (cng_payload_type_ != cng_swb_payload_type_)) 99eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org *cng_payload_type_has_changed = true; 100eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org cng_payload_type_ = cng_swb_payload_type_; 101eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org return true; 102eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org } else if (cng_fb_payload_type_ == payload_type) { 103eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org *frequency = 48000; 104eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org if (cng_payload_type_ != -1 && cng_payload_type_ != cng_fb_payload_type_) 105eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org *cng_payload_type_has_changed = true; 106eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org cng_payload_type_ = cng_fb_payload_type_; 107eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org return true; 108eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org } else { 109eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org // not CNG 110eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org if (g722_payload_type_ == payload_type) { 111eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org last_received_g722_ = true; 112eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org } else { 113eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org last_received_g722_ = false; 114eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org } 115eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org } 116eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org return false; 117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1197fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.orgbool RTPReceiverAudio::ShouldReportCsrcChanges(uint8_t payload_type) const { 120264c0d7ef9e23b5a3ac83306cc9c57eb48c5c101phoglund@webrtc.org // Don't do this for DTMF packets, otherwise it's fine. 121264c0d7ef9e23b5a3ac83306cc9c57eb48c5c101phoglund@webrtc.org return !TelephoneEventPayloadType(payload_type); 122264c0d7ef9e23b5a3ac83306cc9c57eb48c5c101phoglund@webrtc.org} 123264c0d7ef9e23b5a3ac83306cc9c57eb48c5c101phoglund@webrtc.org 124eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - Sample based or frame based codecs based on RFC 3551 125eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - 126eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - NOTE! There is one error in the RFC, stating G.722 uses 8 bits/samples. 127eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - The correct rate is 4 bits/sample. 128eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - 129eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - name of sampling default 130eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - encoding sample/frame bits/sample rate ms/frame ms/packet 131eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - 132eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - Sample based audio codecs 133eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - DVI4 sample 4 var. 20 134eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - G722 sample 4 16,000 20 135eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - G726-40 sample 5 8,000 20 136eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - G726-32 sample 4 8,000 20 137eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - G726-24 sample 3 8,000 20 138eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - G726-16 sample 2 8,000 20 139eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - L8 sample 8 var. 20 140eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - L16 sample 16 var. 20 141eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - PCMA sample 8 var. 20 142eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - PCMU sample 8 var. 20 143eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - 144eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - Frame based audio codecs 145eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - G723 frame N/A 8,000 30 30 146eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - G728 frame N/A 8,000 2.5 20 147eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - G729 frame N/A 8,000 10 20 148eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - G729D frame N/A 8,000 10 20 149eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - G729E frame N/A 8,000 10 20 150eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - GSM frame N/A 8,000 20 20 151eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - GSM-EFR frame N/A 8,000 20 20 152eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - LPC frame N/A 8,000 20 20 153eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - MPA frame N/A var. var. 154eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - 155eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// - G7221 frame N/A 156b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t RTPReceiverAudio::OnNewPayloadTypeCreated( 157eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org const char payload_name[RTP_PAYLOAD_NAME_SIZE], 1587fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org int8_t payload_type, 1597fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org uint32_t frequency) { 1607fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org CriticalSectionScoped lock(crit_sect_.get()); 161f99e60b8fe2bbd68b4fd6bdf3b4070387b786e0cphoglund@webrtc.org 1626aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org if (RtpUtility::StringCompare(payload_name, "telephone-event", 15)) { 163eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org telephone_event_payload_type_ = payload_type; 164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1656aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org if (RtpUtility::StringCompare(payload_name, "cn", 2)) { 166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // we can have three CNG on 8000Hz, 16000Hz and 32000Hz 167eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org if (frequency == 8000) { 168eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org cng_nb_payload_type_ = payload_type; 169eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org } else if (frequency == 16000) { 170eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org cng_wb_payload_type_ = payload_type; 171eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org } else if (frequency == 32000) { 172eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org cng_swb_payload_type_ = payload_type; 173eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org } else if (frequency == 48000) { 174eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org cng_fb_payload_type_ = payload_type; 175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(false); 177e21a5c0c0d2334ff8d3f6dc4647984bca6c08c1fphoglund@webrtc.org return -1; 178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 180e21a5c0c0d2334ff8d3f6dc4647984bca6c08c1fphoglund@webrtc.org return 0; 181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1837fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.orgint32_t RTPReceiverAudio::ParseRtpPacket(WebRtcRTPHeader* rtp_header, 1847fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org const PayloadUnion& specific_payload, 1857fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org bool is_red, 186db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org const uint8_t* payload, 187db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org uint16_t payload_length, 1887fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org int64_t timestamp_ms, 1897fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org bool is_first_packet) { 19074472fe9852769d834e135bde1229c24ab844244hclam@chromium.org TRACE_EVENT2("webrtc_rtp", "Audio::ParseRtp", 19174472fe9852769d834e135bde1229c24ab844244hclam@chromium.org "seqnum", rtp_header->header.sequenceNumber, 19274472fe9852769d834e135bde1229c24ab844244hclam@chromium.org "timestamp", rtp_header->header.timestamp); 1936696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org rtp_header->type.Audio.numEnergy = rtp_header->header.numCSRCs; 1947fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org num_energy_ = rtp_header->type.Audio.numEnergy; 1957fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org if (rtp_header->type.Audio.numEnergy > 0 && 1967fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org rtp_header->type.Audio.numEnergy <= kRtpCsrcSize) { 1977fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org memcpy(current_remote_energy_, 1987fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org rtp_header->type.Audio.arrOfEnergy, 1997fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org rtp_header->type.Audio.numEnergy); 2007fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org } 201eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org 202eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org return ParseAudioCodecSpecific(rtp_header, 203db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org payload, 204424e0e421f9b20569e6fad9274b4085016c6352bminyue@webrtc.org payload_length, 205eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org specific_payload.Audio, 206eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org is_red); 2077d91c10c601030978979529a17edbc51784866cephoglund@webrtc.org} 2087d91c10c601030978979529a17edbc51784866cephoglund@webrtc.org 2097fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.orgint RTPReceiverAudio::GetPayloadTypeFrequency() const { 2107fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org CriticalSectionScoped lock(crit_sect_.get()); 2117fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org if (last_received_g722_) { 2127fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org return 8000; 2137fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org } 2147fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org return last_received_frequency_; 2157d91c10c601030978979529a17edbc51784866cephoglund@webrtc.org} 2167d91c10c601030978979529a17edbc51784866cephoglund@webrtc.org 2177d91c10c601030978979529a17edbc51784866cephoglund@webrtc.orgRTPAliveType RTPReceiverAudio::ProcessDeadOrAlive( 218b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint16_t last_payload_length) const { 219eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org 220eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org // Our CNG is 9 bytes; if it's a likely CNG the receiver needs to check 221eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org // kRtpNoRtp against NetEq speech_type kOutputPLCtoCNG. 222eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org if (last_payload_length < 10) { // our CNG is 9 bytes 223eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org return kRtpNoRtp; 224eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org } else { 225eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org return kRtpDead; 226eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org } 2277d91c10c601030978979529a17edbc51784866cephoglund@webrtc.org} 2287d91c10c601030978979529a17edbc51784866cephoglund@webrtc.org 2297fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.orgvoid RTPReceiverAudio::CheckPayloadChanged(int8_t payload_type, 2307fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org PayloadUnion* specific_payload, 2317fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org bool* should_reset_statistics, 2327fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org bool* should_discard_changes) { 233eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org *should_discard_changes = false; 234eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org *should_reset_statistics = false; 235eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org 236eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org if (TelephoneEventPayloadType(payload_type)) { 2377d91c10c601030978979529a17edbc51784866cephoglund@webrtc.org // Don't do callbacks for DTMF packets. 238eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org *should_discard_changes = true; 2397d91c10c601030978979529a17edbc51784866cephoglund@webrtc.org return; 2407d91c10c601030978979529a17edbc51784866cephoglund@webrtc.org } 2417d91c10c601030978979529a17edbc51784866cephoglund@webrtc.org // frequency is updated for CNG 242eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org bool cng_payload_type_has_changed = false; 243eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org bool is_cng_payload_type = CNGPayloadType(payload_type, 244eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org &specific_payload->Audio.frequency, 245eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org &cng_payload_type_has_changed); 2467d91c10c601030978979529a17edbc51784866cephoglund@webrtc.org 247eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org *should_reset_statistics = cng_payload_type_has_changed; 2487d91c10c601030978979529a17edbc51784866cephoglund@webrtc.org 249eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org if (is_cng_payload_type) { 2507d91c10c601030978979529a17edbc51784866cephoglund@webrtc.org // Don't do callbacks for DTMF packets. 251eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org *should_discard_changes = true; 2527d91c10c601030978979529a17edbc51784866cephoglund@webrtc.org return; 2537d91c10c601030978979529a17edbc51784866cephoglund@webrtc.org } 2547d91c10c601030978979529a17edbc51784866cephoglund@webrtc.org} 2557d91c10c601030978979529a17edbc51784866cephoglund@webrtc.org 2567fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.orgint RTPReceiverAudio::Energy(uint8_t array_of_energy[kRtpCsrcSize]) const { 2577fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org CriticalSectionScoped cs(crit_sect_.get()); 2587fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org 2597fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org assert(num_energy_ <= kRtpCsrcSize); 2607fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org 2617fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org if (num_energy_ > 0) { 2627fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org memcpy(array_of_energy, current_remote_energy_, 2637fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org sizeof(uint8_t) * num_energy_); 2647fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org } 2657fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org return num_energy_; 2667fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org} 2677fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org 268b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t RTPReceiverAudio::InvokeOnInitializeDecoder( 269eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org RtpFeedback* callback, 2707fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org int32_t id, 2717fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org int8_t payload_type, 272eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org const char payload_name[RTP_PAYLOAD_NAME_SIZE], 2737fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org const PayloadUnion& specific_payload) const { 274eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org if (-1 == callback->OnInitializeDecoder(id, 275eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org payload_type, 276eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org payload_name, 277eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org specific_payload.Audio.frequency, 278eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org specific_payload.Audio.channels, 279eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org specific_payload.Audio.rate)) { 28099681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org LOG(LS_ERROR) << "Failed to create decoder for payload type: " 28199681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org << payload_name << "/" << payload_type; 2827d91c10c601030978979529a17edbc51784866cephoglund@webrtc.org return -1; 2837d91c10c601030978979529a17edbc51784866cephoglund@webrtc.org } 2847d91c10c601030978979529a17edbc51784866cephoglund@webrtc.org return 0; 2857d91c10c601030978979529a17edbc51784866cephoglund@webrtc.org} 2867d91c10c601030978979529a17edbc51784866cephoglund@webrtc.org 287eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org// We are not allowed to have any critsects when calling data_callback. 288b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint32_t RTPReceiverAudio::ParseAudioCodecSpecific( 289eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org WebRtcRTPHeader* rtp_header, 290b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org const uint8_t* payload_data, 2917fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org uint16_t payload_length, 2927fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org const AudioPayload& audio_specific, 2937fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org bool is_red) { 294eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org 295eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org if (payload_length == 0) { 296eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org return 0; 297eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org } 298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 299eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org bool telephone_event_packet = 300eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org TelephoneEventPayloadType(rtp_header->header.payloadType); 301eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org if (telephone_event_packet) { 3027fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org CriticalSectionScoped lock(crit_sect_.get()); 303eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org 304eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org // RFC 4733 2.3 305eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org // 0 1 2 3 306eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org // 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 307eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 308eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org // | event |E|R| volume | duration | 309eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 310eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org // 311eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org if (payload_length % 4 != 0) { 312eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org return -1; 313eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org } 314b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint8_t number_of_events = payload_length / 4; 315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 316eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org // sanity 317eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org if (number_of_events >= MAX_NUMBER_OF_PARALLEL_TELEPHONE_EVENTS) { 318eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org number_of_events = MAX_NUMBER_OF_PARALLEL_TELEPHONE_EVENTS; 319eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org } 320eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org for (int n = 0; n < number_of_events; ++n) { 321eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org bool end = (payload_data[(4 * n) + 1] & 0x80) ? true : false; 322eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org 323b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org std::set<uint8_t>::iterator event = 324eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org telephone_event_reported_.find(payload_data[4 * n]); 325eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org 326eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org if (event != telephone_event_reported_.end()) { 327eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org // we have already seen this event 328eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org if (end) { 329eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org telephone_event_reported_.erase(payload_data[4 * n]); 330f99e60b8fe2bbd68b4fd6bdf3b4070387b786e0cphoglund@webrtc.org } 331eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org } else { 332eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org if (end) { 333eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org // don't add if it's a end of a tone 334eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org } else { 335eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org telephone_event_reported_.insert(payload_data[4 * n]); 336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 337eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org } 338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 340eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org // RFC 4733 2.5.1.3 & 2.5.2.3 Long-Duration Events 341eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org // should not be a problem since we don't care about the duration 342f99e60b8fe2bbd68b4fd6bdf3b4070387b786e0cphoglund@webrtc.org 343eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org // RFC 4733 See 2.5.1.5. & 2.5.2.4. Multiple Events in a Packet 344eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org } 345f99e60b8fe2bbd68b4fd6bdf3b4070387b786e0cphoglund@webrtc.org 346eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org { 3477fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org CriticalSectionScoped lock(crit_sect_.get()); 348f99e60b8fe2bbd68b4fd6bdf3b4070387b786e0cphoglund@webrtc.org 349eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org if (!telephone_event_packet) { 350eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org last_received_frequency_ = audio_specific.frequency; 351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 352eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org 353eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org // Check if this is a CNG packet, receiver might want to know 354b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org uint32_t ignored; 355eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org bool also_ignored; 356eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org if (CNGPayloadType(rtp_header->header.payloadType, 357eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org &ignored, 358eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org &also_ignored)) { 359eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org rtp_header->type.Audio.isCNG = true; 360eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org rtp_header->frameType = kAudioFrameCN; 361eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org } else { 362eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org rtp_header->frameType = kAudioFrameSpeech; 363eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org rtp_header->type.Audio.isCNG = false; 364eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org } 365eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org 366eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org // check if it's a DTMF event, hence something we can playout 367eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org if (telephone_event_packet) { 368eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org if (!telephone_event_forward_to_decoder_) { 369eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org // don't forward event to decoder 370eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org return 0; 371eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org } 372b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org std::set<uint8_t>::iterator first = 373eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org telephone_event_reported_.begin(); 374eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org if (first != telephone_event_reported_.end() && *first > 15) { 375eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org // don't forward non DTMF events 376eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org return 0; 377eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org } 378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 379eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org } 380db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org // TODO(holmer): Break this out to have RED parsing handled generically. 381eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org if (is_red && !(payload_data[0] & 0x80)) { 382eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org // we recive only one frame packed in a RED packet remove the RED wrapper 383eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org rtp_header->header.payloadType = payload_data[0]; 384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 385eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org // only one frame in the RED strip the one byte to help NetEq 386cd29867e6b49df11e565dcb1d64dbe92751b509cphoglund@webrtc.org return data_callback_->OnReceivedPayloadData( 387eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org payload_data + 1, payload_length - 1, rtp_header); 388eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org } 389eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org 390eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org rtp_header->type.Audio.channel = audio_specific.channels; 391eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org return data_callback_->OnReceivedPayloadData( 392eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org payload_data, payload_length, rtp_header); 393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 394eadcc4de1aa972ca237e1d41a294edf93659d702phoglund@webrtc.org} // namespace webrtc 395