diff options
Diffstat (limited to 'webrtc/modules/audio_coding/acm2/audio_coding_module_impl.h')
-rw-r--r-- | webrtc/modules/audio_coding/acm2/audio_coding_module_impl.h | 283 |
1 files changed, 283 insertions, 0 deletions
diff --git a/webrtc/modules/audio_coding/acm2/audio_coding_module_impl.h b/webrtc/modules/audio_coding/acm2/audio_coding_module_impl.h new file mode 100644 index 0000000000..926671f199 --- /dev/null +++ b/webrtc/modules/audio_coding/acm2/audio_coding_module_impl.h @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_AUDIO_CODING_ACM2_AUDIO_CODING_MODULE_IMPL_H_ +#define WEBRTC_MODULES_AUDIO_CODING_ACM2_AUDIO_CODING_MODULE_IMPL_H_ + +#include <string> +#include <vector> + +#include "webrtc/base/buffer.h" +#include "webrtc/base/scoped_ptr.h" +#include "webrtc/base/thread_annotations.h" +#include "webrtc/common_types.h" +#include "webrtc/engine_configurations.h" +#include "webrtc/modules/audio_coding/acm2/acm_receiver.h" +#include "webrtc/modules/audio_coding/acm2/acm_resampler.h" +#include "webrtc/modules/audio_coding/acm2/codec_manager.h" + +namespace webrtc { + +class CriticalSectionWrapper; +class AudioCodingImpl; + +namespace acm2 { + +class AudioCodingModuleImpl final : public AudioCodingModule { + public: + friend webrtc::AudioCodingImpl; + + explicit AudioCodingModuleImpl(const AudioCodingModule::Config& config); + ~AudioCodingModuleImpl() override; + + ///////////////////////////////////////// + // Sender + // + + // Can be called multiple times for Codec, CNG, RED. + int RegisterSendCodec(const CodecInst& send_codec) override; + + void RegisterExternalSendCodec( + AudioEncoder* external_speech_encoder) override; + + // Get current send codec. + rtc::Optional<CodecInst> SendCodec() const override; + + // Get current send frequency. + int SendFrequency() const override; + + // Sets the bitrate to the specified value in bits/sec. In case the codec does + // not support the requested value it will choose an appropriate value + // instead. + void SetBitRate(int bitrate_bps) override; + + // Register a transport callback which will be + // called to deliver the encoded buffers. + int RegisterTransportCallback(AudioPacketizationCallback* transport) override; + + // Add 10 ms of raw (PCM) audio data to the encoder. + int Add10MsData(const AudioFrame& audio_frame) override; + + ///////////////////////////////////////// + // (RED) Redundant Coding + // + + // Configure RED status i.e. on/off. + int SetREDStatus(bool enable_red) override; + + // Get RED status. + bool REDStatus() const override; + + ///////////////////////////////////////// + // (FEC) Forward Error Correction (codec internal) + // + + // Configure FEC status i.e. on/off. + int SetCodecFEC(bool enabled_codec_fec) override; + + // Get FEC status. + bool CodecFEC() const override; + + // Set target packet loss rate + int SetPacketLossRate(int loss_rate) override; + + ///////////////////////////////////////// + // (VAD) Voice Activity Detection + // and + // (CNG) Comfort Noise Generation + // + + int SetVAD(bool enable_dtx = true, + bool enable_vad = false, + ACMVADMode mode = VADNormal) override; + + int VAD(bool* dtx_enabled, + bool* vad_enabled, + ACMVADMode* mode) const override; + + int RegisterVADCallback(ACMVADCallback* vad_callback) override; + + ///////////////////////////////////////// + // Receiver + // + + // Initialize receiver, resets codec database etc. + int InitializeReceiver() override; + + // Get current receive frequency. + int ReceiveFrequency() const override; + + // Get current playout frequency. + int PlayoutFrequency() const override; + + // Register possible receive codecs, can be called multiple times, + // for codecs, CNG, DTMF, RED. + int RegisterReceiveCodec(const CodecInst& receive_codec) override; + + int RegisterExternalReceiveCodec(int rtp_payload_type, + AudioDecoder* external_decoder, + int sample_rate_hz, + int num_channels, + const std::string& name) override; + + // Get current received codec. + int ReceiveCodec(CodecInst* current_codec) const override; + + // Incoming packet from network parsed and ready for decode. + int IncomingPacket(const uint8_t* incoming_payload, + const size_t payload_length, + const WebRtcRTPHeader& rtp_info) override; + + // Incoming payloads, without rtp-info, the rtp-info will be created in ACM. + // One usage for this API is when pre-encoded files are pushed in ACM. + int IncomingPayload(const uint8_t* incoming_payload, + const size_t payload_length, + uint8_t payload_type, + uint32_t timestamp) override; + + // Minimum playout delay. + int SetMinimumPlayoutDelay(int time_ms) override; + + // Maximum playout delay. + int SetMaximumPlayoutDelay(int time_ms) override; + + // Smallest latency NetEq will maintain. + int LeastRequiredDelayMs() const override; + + // Get playout timestamp. + int PlayoutTimestamp(uint32_t* timestamp) override; + + // Get 10 milliseconds of raw audio data to play out, and + // automatic resample to the requested frequency if > 0. + int PlayoutData10Ms(int desired_freq_hz, AudioFrame* audio_frame) override; + + ///////////////////////////////////////// + // Statistics + // + + int GetNetworkStatistics(NetworkStatistics* statistics) override; + + int SetOpusApplication(OpusApplicationMode application) override; + + // If current send codec is Opus, informs it about the maximum playback rate + // the receiver will render. + int SetOpusMaxPlaybackRate(int frequency_hz) override; + + int EnableOpusDtx() override; + + int DisableOpusDtx() override; + + int UnregisterReceiveCodec(uint8_t payload_type) override; + + int EnableNack(size_t max_nack_list_size) override; + + void DisableNack() override; + + std::vector<uint16_t> GetNackList(int64_t round_trip_time_ms) const override; + + void GetDecodingCallStatistics(AudioDecodingCallStats* stats) const override; + + private: + struct InputData { + uint32_t input_timestamp; + const int16_t* audio; + size_t length_per_channel; + size_t audio_channel; + // If a re-mix is required (up or down), this buffer will store a re-mixed + // version of the input. + int16_t buffer[WEBRTC_10MS_PCM_AUDIO]; + }; + + // This member class writes values to the named UMA histogram, but only if + // the value has changed since the last time (and always for the first call). + class ChangeLogger { + public: + explicit ChangeLogger(const std::string& histogram_name) + : histogram_name_(histogram_name) {} + // Logs the new value if it is different from the last logged value, or if + // this is the first call. + void MaybeLog(int value); + + private: + int last_value_ = 0; + int first_time_ = true; + const std::string histogram_name_; + }; + + int Add10MsDataInternal(const AudioFrame& audio_frame, InputData* input_data) + EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_); + int Encode(const InputData& input_data) + EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_); + + int InitializeReceiverSafe() EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_); + + bool HaveValidEncoder(const char* caller_name) const + EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_); + + // Preprocessing of input audio, including resampling and down-mixing if + // required, before pushing audio into encoder's buffer. + // + // in_frame: input audio-frame + // ptr_out: pointer to output audio_frame. If no preprocessing is required + // |ptr_out| will be pointing to |in_frame|, otherwise pointing to + // |preprocess_frame_|. + // + // Return value: + // -1: if encountering an error. + // 0: otherwise. + int PreprocessToAddData(const AudioFrame& in_frame, + const AudioFrame** ptr_out) + EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_); + + // Change required states after starting to receive the codec corresponding + // to |index|. + int UpdateUponReceivingCodec(int index); + + const rtc::scoped_ptr<CriticalSectionWrapper> acm_crit_sect_; + rtc::Buffer encode_buffer_ GUARDED_BY(acm_crit_sect_); + int id_; // TODO(henrik.lundin) Make const. + uint32_t expected_codec_ts_ GUARDED_BY(acm_crit_sect_); + uint32_t expected_in_ts_ GUARDED_BY(acm_crit_sect_); + ACMResampler resampler_ GUARDED_BY(acm_crit_sect_); + AcmReceiver receiver_; // AcmReceiver has it's own internal lock. + ChangeLogger bitrate_logger_ GUARDED_BY(acm_crit_sect_); + CodecManager codec_manager_ GUARDED_BY(acm_crit_sect_); + RentACodec rent_a_codec_ GUARDED_BY(acm_crit_sect_); + + // This is to keep track of CN instances where we can send DTMFs. + uint8_t previous_pltype_ GUARDED_BY(acm_crit_sect_); + + // Used when payloads are pushed into ACM without any RTP info + // One example is when pre-encoded bit-stream is pushed from + // a file. + // IMPORTANT: this variable is only used in IncomingPayload(), therefore, + // no lock acquired when interacting with this variable. If it is going to + // be used in other methods, locks need to be taken. + rtc::scoped_ptr<WebRtcRTPHeader> aux_rtp_header_; + + bool receiver_initialized_ GUARDED_BY(acm_crit_sect_); + + AudioFrame preprocess_frame_ GUARDED_BY(acm_crit_sect_); + bool first_10ms_data_ GUARDED_BY(acm_crit_sect_); + + bool first_frame_ GUARDED_BY(acm_crit_sect_); + uint32_t last_timestamp_ GUARDED_BY(acm_crit_sect_); + uint32_t last_rtp_timestamp_ GUARDED_BY(acm_crit_sect_); + + const rtc::scoped_ptr<CriticalSectionWrapper> callback_crit_sect_; + AudioPacketizationCallback* packetization_callback_ + GUARDED_BY(callback_crit_sect_); + ACMVADCallback* vad_callback_ GUARDED_BY(callback_crit_sect_); +}; + +} // namespace acm2 +} // namespace webrtc + +#endif // WEBRTC_MODULES_AUDIO_CODING_ACM2_AUDIO_CODING_MODULE_IMPL_H_ |