aboutsummaryrefslogtreecommitdiff
path: root/webrtc/modules/audio_coding/acm2/audio_coding_module_impl.h
diff options
context:
space:
mode:
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.h283
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_