| OLD | NEW |
| (Empty) |
| 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 #ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_AUDIO_CODING_MODULE_IMPL_H_ | |
| 12 #define WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_AUDIO_CODING_MODULE_IMPL_H_ | |
| 13 | |
| 14 #include <vector> | |
| 15 | |
| 16 #include "webrtc/base/buffer.h" | |
| 17 #include "webrtc/base/scoped_ptr.h" | |
| 18 #include "webrtc/base/thread_annotations.h" | |
| 19 #include "webrtc/common_types.h" | |
| 20 #include "webrtc/engine_configurations.h" | |
| 21 #include "webrtc/modules/audio_coding/main/acm2/acm_receiver.h" | |
| 22 #include "webrtc/modules/audio_coding/main/acm2/acm_resampler.h" | |
| 23 #include "webrtc/modules/audio_coding/main/acm2/codec_manager.h" | |
| 24 | |
| 25 namespace webrtc { | |
| 26 | |
| 27 class CriticalSectionWrapper; | |
| 28 class AudioCodingImpl; | |
| 29 | |
| 30 namespace acm2 { | |
| 31 | |
| 32 class AudioCodingModuleImpl final : public AudioCodingModule { | |
| 33 public: | |
| 34 friend webrtc::AudioCodingImpl; | |
| 35 | |
| 36 explicit AudioCodingModuleImpl(const AudioCodingModule::Config& config); | |
| 37 ~AudioCodingModuleImpl() override; | |
| 38 | |
| 39 ///////////////////////////////////////// | |
| 40 // Sender | |
| 41 // | |
| 42 | |
| 43 // Can be called multiple times for Codec, CNG, RED. | |
| 44 int RegisterSendCodec(const CodecInst& send_codec) override; | |
| 45 | |
| 46 void RegisterExternalSendCodec( | |
| 47 AudioEncoder* external_speech_encoder) override; | |
| 48 | |
| 49 // Get current send codec. | |
| 50 rtc::Optional<CodecInst> SendCodec() const override; | |
| 51 | |
| 52 // Get current send frequency. | |
| 53 int SendFrequency() const override; | |
| 54 | |
| 55 // Sets the bitrate to the specified value in bits/sec. In case the codec does | |
| 56 // not support the requested value it will choose an appropriate value | |
| 57 // instead. | |
| 58 void SetBitRate(int bitrate_bps) override; | |
| 59 | |
| 60 // Register a transport callback which will be | |
| 61 // called to deliver the encoded buffers. | |
| 62 int RegisterTransportCallback(AudioPacketizationCallback* transport) override; | |
| 63 | |
| 64 // Add 10 ms of raw (PCM) audio data to the encoder. | |
| 65 int Add10MsData(const AudioFrame& audio_frame) override; | |
| 66 | |
| 67 ///////////////////////////////////////// | |
| 68 // (RED) Redundant Coding | |
| 69 // | |
| 70 | |
| 71 // Configure RED status i.e. on/off. | |
| 72 int SetREDStatus(bool enable_red) override; | |
| 73 | |
| 74 // Get RED status. | |
| 75 bool REDStatus() const override; | |
| 76 | |
| 77 ///////////////////////////////////////// | |
| 78 // (FEC) Forward Error Correction (codec internal) | |
| 79 // | |
| 80 | |
| 81 // Configure FEC status i.e. on/off. | |
| 82 int SetCodecFEC(bool enabled_codec_fec) override; | |
| 83 | |
| 84 // Get FEC status. | |
| 85 bool CodecFEC() const override; | |
| 86 | |
| 87 // Set target packet loss rate | |
| 88 int SetPacketLossRate(int loss_rate) override; | |
| 89 | |
| 90 ///////////////////////////////////////// | |
| 91 // (VAD) Voice Activity Detection | |
| 92 // and | |
| 93 // (CNG) Comfort Noise Generation | |
| 94 // | |
| 95 | |
| 96 int SetVAD(bool enable_dtx = true, | |
| 97 bool enable_vad = false, | |
| 98 ACMVADMode mode = VADNormal) override; | |
| 99 | |
| 100 int VAD(bool* dtx_enabled, | |
| 101 bool* vad_enabled, | |
| 102 ACMVADMode* mode) const override; | |
| 103 | |
| 104 int RegisterVADCallback(ACMVADCallback* vad_callback) override; | |
| 105 | |
| 106 ///////////////////////////////////////// | |
| 107 // Receiver | |
| 108 // | |
| 109 | |
| 110 // Initialize receiver, resets codec database etc. | |
| 111 int InitializeReceiver() override; | |
| 112 | |
| 113 // Get current receive frequency. | |
| 114 int ReceiveFrequency() const override; | |
| 115 | |
| 116 // Get current playout frequency. | |
| 117 int PlayoutFrequency() const override; | |
| 118 | |
| 119 // Register possible receive codecs, can be called multiple times, | |
| 120 // for codecs, CNG, DTMF, RED. | |
| 121 int RegisterReceiveCodec(const CodecInst& receive_codec) override; | |
| 122 | |
| 123 int RegisterExternalReceiveCodec(int rtp_payload_type, | |
| 124 AudioDecoder* external_decoder, | |
| 125 int sample_rate_hz, | |
| 126 int num_channels) override; | |
| 127 | |
| 128 // Get current received codec. | |
| 129 int ReceiveCodec(CodecInst* current_codec) const override; | |
| 130 | |
| 131 // Incoming packet from network parsed and ready for decode. | |
| 132 int IncomingPacket(const uint8_t* incoming_payload, | |
| 133 const size_t payload_length, | |
| 134 const WebRtcRTPHeader& rtp_info) override; | |
| 135 | |
| 136 // Incoming payloads, without rtp-info, the rtp-info will be created in ACM. | |
| 137 // One usage for this API is when pre-encoded files are pushed in ACM. | |
| 138 int IncomingPayload(const uint8_t* incoming_payload, | |
| 139 const size_t payload_length, | |
| 140 uint8_t payload_type, | |
| 141 uint32_t timestamp) override; | |
| 142 | |
| 143 // Minimum playout delay. | |
| 144 int SetMinimumPlayoutDelay(int time_ms) override; | |
| 145 | |
| 146 // Maximum playout delay. | |
| 147 int SetMaximumPlayoutDelay(int time_ms) override; | |
| 148 | |
| 149 // Smallest latency NetEq will maintain. | |
| 150 int LeastRequiredDelayMs() const override; | |
| 151 | |
| 152 // Get playout timestamp. | |
| 153 int PlayoutTimestamp(uint32_t* timestamp) override; | |
| 154 | |
| 155 // Get 10 milliseconds of raw audio data to play out, and | |
| 156 // automatic resample to the requested frequency if > 0. | |
| 157 int PlayoutData10Ms(int desired_freq_hz, AudioFrame* audio_frame) override; | |
| 158 | |
| 159 ///////////////////////////////////////// | |
| 160 // Statistics | |
| 161 // | |
| 162 | |
| 163 int GetNetworkStatistics(NetworkStatistics* statistics) override; | |
| 164 | |
| 165 int SetOpusApplication(OpusApplicationMode application) override; | |
| 166 | |
| 167 // If current send codec is Opus, informs it about the maximum playback rate | |
| 168 // the receiver will render. | |
| 169 int SetOpusMaxPlaybackRate(int frequency_hz) override; | |
| 170 | |
| 171 int EnableOpusDtx() override; | |
| 172 | |
| 173 int DisableOpusDtx() override; | |
| 174 | |
| 175 int UnregisterReceiveCodec(uint8_t payload_type) override; | |
| 176 | |
| 177 int EnableNack(size_t max_nack_list_size) override; | |
| 178 | |
| 179 void DisableNack() override; | |
| 180 | |
| 181 std::vector<uint16_t> GetNackList(int64_t round_trip_time_ms) const override; | |
| 182 | |
| 183 void GetDecodingCallStatistics(AudioDecodingCallStats* stats) const override; | |
| 184 | |
| 185 private: | |
| 186 struct InputData { | |
| 187 uint32_t input_timestamp; | |
| 188 const int16_t* audio; | |
| 189 size_t length_per_channel; | |
| 190 uint8_t audio_channel; | |
| 191 // If a re-mix is required (up or down), this buffer will store a re-mixed | |
| 192 // version of the input. | |
| 193 int16_t buffer[WEBRTC_10MS_PCM_AUDIO]; | |
| 194 }; | |
| 195 | |
| 196 // This member class writes values to the named UMA histogram, but only if | |
| 197 // the value has changed since the last time (and always for the first call). | |
| 198 class ChangeLogger { | |
| 199 public: | |
| 200 explicit ChangeLogger(const std::string& histogram_name) | |
| 201 : histogram_name_(histogram_name) {} | |
| 202 // Logs the new value if it is different from the last logged value, or if | |
| 203 // this is the first call. | |
| 204 void MaybeLog(int value); | |
| 205 | |
| 206 private: | |
| 207 int last_value_ = 0; | |
| 208 int first_time_ = true; | |
| 209 const std::string histogram_name_; | |
| 210 }; | |
| 211 | |
| 212 int Add10MsDataInternal(const AudioFrame& audio_frame, InputData* input_data) | |
| 213 EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_); | |
| 214 int Encode(const InputData& input_data) | |
| 215 EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_); | |
| 216 | |
| 217 int InitializeReceiverSafe() EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_); | |
| 218 | |
| 219 bool HaveValidEncoder(const char* caller_name) const | |
| 220 EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_); | |
| 221 | |
| 222 // Preprocessing of input audio, including resampling and down-mixing if | |
| 223 // required, before pushing audio into encoder's buffer. | |
| 224 // | |
| 225 // in_frame: input audio-frame | |
| 226 // ptr_out: pointer to output audio_frame. If no preprocessing is required | |
| 227 // |ptr_out| will be pointing to |in_frame|, otherwise pointing to | |
| 228 // |preprocess_frame_|. | |
| 229 // | |
| 230 // Return value: | |
| 231 // -1: if encountering an error. | |
| 232 // 0: otherwise. | |
| 233 int PreprocessToAddData(const AudioFrame& in_frame, | |
| 234 const AudioFrame** ptr_out) | |
| 235 EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_); | |
| 236 | |
| 237 // Change required states after starting to receive the codec corresponding | |
| 238 // to |index|. | |
| 239 int UpdateUponReceivingCodec(int index); | |
| 240 | |
| 241 const rtc::scoped_ptr<CriticalSectionWrapper> acm_crit_sect_; | |
| 242 rtc::Buffer encode_buffer_ GUARDED_BY(acm_crit_sect_); | |
| 243 int id_; // TODO(henrik.lundin) Make const. | |
| 244 uint32_t expected_codec_ts_ GUARDED_BY(acm_crit_sect_); | |
| 245 uint32_t expected_in_ts_ GUARDED_BY(acm_crit_sect_); | |
| 246 ACMResampler resampler_ GUARDED_BY(acm_crit_sect_); | |
| 247 AcmReceiver receiver_; // AcmReceiver has it's own internal lock. | |
| 248 ChangeLogger bitrate_logger_ GUARDED_BY(acm_crit_sect_); | |
| 249 CodecManager codec_manager_ GUARDED_BY(acm_crit_sect_); | |
| 250 | |
| 251 // This is to keep track of CN instances where we can send DTMFs. | |
| 252 uint8_t previous_pltype_ GUARDED_BY(acm_crit_sect_); | |
| 253 | |
| 254 // Used when payloads are pushed into ACM without any RTP info | |
| 255 // One example is when pre-encoded bit-stream is pushed from | |
| 256 // a file. | |
| 257 // IMPORTANT: this variable is only used in IncomingPayload(), therefore, | |
| 258 // no lock acquired when interacting with this variable. If it is going to | |
| 259 // be used in other methods, locks need to be taken. | |
| 260 rtc::scoped_ptr<WebRtcRTPHeader> aux_rtp_header_; | |
| 261 | |
| 262 bool receiver_initialized_ GUARDED_BY(acm_crit_sect_); | |
| 263 | |
| 264 AudioFrame preprocess_frame_ GUARDED_BY(acm_crit_sect_); | |
| 265 bool first_10ms_data_ GUARDED_BY(acm_crit_sect_); | |
| 266 | |
| 267 bool first_frame_ GUARDED_BY(acm_crit_sect_); | |
| 268 uint32_t last_timestamp_ GUARDED_BY(acm_crit_sect_); | |
| 269 uint32_t last_rtp_timestamp_ GUARDED_BY(acm_crit_sect_); | |
| 270 | |
| 271 const rtc::scoped_ptr<CriticalSectionWrapper> callback_crit_sect_; | |
| 272 AudioPacketizationCallback* packetization_callback_ | |
| 273 GUARDED_BY(callback_crit_sect_); | |
| 274 ACMVADCallback* vad_callback_ GUARDED_BY(callback_crit_sect_); | |
| 275 }; | |
| 276 | |
| 277 } // namespace acm2 | |
| 278 } // namespace webrtc | |
| 279 | |
| 280 #endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_AUDIO_CODING_MODULE_IMPL_H_ | |
| OLD | NEW |