Home | History | Annotate | Download | only in acm2
      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/common_types.h"
     17 #include "webrtc/engine_configurations.h"
     18 #include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h"
     19 #include "webrtc/modules/audio_coding/main/acm2/acm_receiver.h"
     20 #include "webrtc/modules/audio_coding/main/acm2/acm_resampler.h"
     21 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
     22 #include "webrtc/system_wrappers/interface/thread_annotations.h"
     23 
     24 namespace webrtc {
     25 
     26 class CriticalSectionWrapper;
     27 
     28 namespace acm2 {
     29 
     30 class ACMDTMFDetection;
     31 class ACMGenericCodec;
     32 
     33 class AudioCodingModuleImpl : public AudioCodingModule {
     34  public:
     35   explicit AudioCodingModuleImpl(const AudioCodingModule::Config& config);
     36   ~AudioCodingModuleImpl();
     37 
     38   // Change the unique identifier of this object.
     39   virtual int32_t ChangeUniqueId(const int32_t id);
     40 
     41   // Returns the number of milliseconds until the module want a worker thread
     42   // to call Process.
     43   int32_t TimeUntilNextProcess();
     44 
     45   // Process any pending tasks such as timeouts.
     46   int32_t Process();
     47 
     48   /////////////////////////////////////////
     49   //   Sender
     50   //
     51 
     52   // Initialize send codec.
     53   int InitializeSender();
     54 
     55   // Reset send codec.
     56   int ResetEncoder();
     57 
     58   // Can be called multiple times for Codec, CNG, RED.
     59   int RegisterSendCodec(const CodecInst& send_codec);
     60 
     61   // Register Secondary codec for dual-streaming. Dual-streaming is activated
     62   // right after the secondary codec is registered.
     63   int RegisterSecondarySendCodec(const CodecInst& send_codec);
     64 
     65   // Unregister the secondary codec. Dual-streaming is deactivated right after
     66   // deregistering secondary codec.
     67   void UnregisterSecondarySendCodec();
     68 
     69   // Get the secondary codec.
     70   int SecondarySendCodec(CodecInst* secondary_codec) const;
     71 
     72   // Get current send codec.
     73   int SendCodec(CodecInst* current_codec) const;
     74 
     75   // Get current send frequency.
     76   int SendFrequency() const;
     77 
     78   // Get encode bit-rate.
     79   // Adaptive rate codecs return their current encode target rate, while other
     80   // codecs return there long-term average or their fixed rate.
     81   int SendBitrate() const;
     82 
     83   // Set available bandwidth, inform the encoder about the
     84   // estimated bandwidth received from the remote party.
     85   virtual int SetReceivedEstimatedBandwidth(int bw);
     86 
     87   // Register a transport callback which will be
     88   // called to deliver the encoded buffers.
     89   int RegisterTransportCallback(AudioPacketizationCallback* transport);
     90 
     91   // Add 10 ms of raw (PCM) audio data to the encoder.
     92   int Add10MsData(const AudioFrame& audio_frame);
     93 
     94   /////////////////////////////////////////
     95   // (RED) Redundant Coding
     96   //
     97 
     98   // Configure RED status i.e. on/off.
     99   int SetREDStatus(bool enable_red);
    100 
    101   // Get RED status.
    102   bool REDStatus() const;
    103 
    104   /////////////////////////////////////////
    105   // (FEC) Forward Error Correction (codec internal)
    106   //
    107 
    108   // Configure FEC status i.e. on/off.
    109   int SetCodecFEC(bool enabled_codec_fec);
    110 
    111   // Get FEC status.
    112   bool CodecFEC() const;
    113 
    114   // Set target packet loss rate
    115   int SetPacketLossRate(int loss_rate);
    116 
    117   /////////////////////////////////////////
    118   //   (VAD) Voice Activity Detection
    119   //   and
    120   //   (CNG) Comfort Noise Generation
    121   //
    122 
    123   int SetVAD(bool enable_dtx = true,
    124              bool enable_vad = false,
    125              ACMVADMode mode = VADNormal);
    126 
    127   int VAD(bool* dtx_enabled, bool* vad_enabled, ACMVADMode* mode) const;
    128 
    129   int RegisterVADCallback(ACMVADCallback* vad_callback);
    130 
    131   /////////////////////////////////////////
    132   //   Receiver
    133   //
    134 
    135   // Initialize receiver, resets codec database etc.
    136   int InitializeReceiver();
    137 
    138   // Reset the decoder state.
    139   int ResetDecoder();
    140 
    141   // Get current receive frequency.
    142   int ReceiveFrequency() const;
    143 
    144   // Get current playout frequency.
    145   int PlayoutFrequency() const;
    146 
    147   // Register possible receive codecs, can be called multiple times,
    148   // for codecs, CNG, DTMF, RED.
    149   int RegisterReceiveCodec(const CodecInst& receive_codec);
    150 
    151   // Get current received codec.
    152   int ReceiveCodec(CodecInst* current_codec) const;
    153 
    154   // Incoming packet from network parsed and ready for decode.
    155   int IncomingPacket(const uint8_t* incoming_payload,
    156                      int payload_length,
    157                      const WebRtcRTPHeader& rtp_info);
    158 
    159   // Incoming payloads, without rtp-info, the rtp-info will be created in ACM.
    160   // One usage for this API is when pre-encoded files are pushed in ACM.
    161   int IncomingPayload(const uint8_t* incoming_payload,
    162                       int payload_length,
    163                       uint8_t payload_type,
    164                       uint32_t timestamp);
    165 
    166   // Minimum playout delay.
    167   int SetMinimumPlayoutDelay(int time_ms);
    168 
    169   // Maximum playout delay.
    170   int SetMaximumPlayoutDelay(int time_ms);
    171 
    172   // Smallest latency NetEq will maintain.
    173   int LeastRequiredDelayMs() const;
    174 
    175   // Impose an initial delay on playout. ACM plays silence until |delay_ms|
    176   // audio is accumulated in NetEq buffer, then starts decoding payloads.
    177   int SetInitialPlayoutDelay(int delay_ms);
    178 
    179   // TODO(turajs): DTMF playout is always activated in NetEq these APIs should
    180   // be removed, as well as all VoE related APIs and methods.
    181   //
    182   // Configure Dtmf playout status i.e on/off playout the incoming outband Dtmf
    183   // tone.
    184   int SetDtmfPlayoutStatus(bool enable) { return 0; }
    185 
    186   // Get Dtmf playout status.
    187   bool DtmfPlayoutStatus() const { return true; }
    188 
    189   // Estimate the Bandwidth based on the incoming stream, needed
    190   // for one way audio where the RTCP send the BW estimate.
    191   // This is also done in the RTP module .
    192   int DecoderEstimatedBandwidth() const;
    193 
    194   // Set playout mode voice, fax.
    195   int SetPlayoutMode(AudioPlayoutMode mode);
    196 
    197   // Get playout mode voice, fax.
    198   AudioPlayoutMode PlayoutMode() const;
    199 
    200   // Get playout timestamp.
    201   int PlayoutTimestamp(uint32_t* timestamp);
    202 
    203   // Get 10 milliseconds of raw audio data to play out, and
    204   // automatic resample to the requested frequency if > 0.
    205   int PlayoutData10Ms(int desired_freq_hz, AudioFrame* audio_frame);
    206 
    207   /////////////////////////////////////////
    208   //   Statistics
    209   //
    210 
    211   int NetworkStatistics(ACMNetworkStatistics* statistics);
    212 
    213   void DestructEncoderInst(void* inst);
    214 
    215   // GET RED payload for iSAC. The method id called when 'this' ACM is
    216   // the default ACM.
    217   int REDPayloadISAC(int isac_rate,
    218                      int isac_bw_estimate,
    219                      uint8_t* payload,
    220                      int16_t* length_bytes);
    221 
    222   int ReplaceInternalDTXWithWebRtc(bool use_webrtc_dtx);
    223 
    224   int IsInternalDTXReplacedWithWebRtc(bool* uses_webrtc_dtx);
    225 
    226   int SetISACMaxRate(int max_bit_per_sec);
    227 
    228   int SetISACMaxPayloadSize(int max_size_bytes);
    229 
    230   int ConfigISACBandwidthEstimator(int frame_size_ms,
    231                                    int rate_bit_per_sec,
    232                                    bool enforce_frame_size = false);
    233 
    234   int UnregisterReceiveCodec(uint8_t payload_type);
    235 
    236   int EnableNack(size_t max_nack_list_size);
    237 
    238   void DisableNack();
    239 
    240   std::vector<uint16_t> GetNackList(int round_trip_time_ms) const;
    241 
    242   void GetDecodingCallStatistics(AudioDecodingCallStats* stats) const;
    243 
    244  private:
    245   int UnregisterReceiveCodecSafe(int payload_type);
    246 
    247   ACMGenericCodec* CreateCodec(const CodecInst& codec);
    248 
    249   int InitializeReceiverSafe() EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_);
    250 
    251   bool HaveValidEncoder(const char* caller_name) const;
    252 
    253   // Set VAD/DTX status. This function does not acquire a lock, and it is
    254   // created to be called only from inside a critical section.
    255   int SetVADSafe(bool enable_dtx, bool enable_vad, ACMVADMode mode)
    256       EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_);
    257 
    258   // Process buffered audio when dual-streaming is not enabled (When RED is
    259   // enabled still this function is used.)
    260   int ProcessSingleStream();
    261 
    262   // Process buffered audio when dual-streaming is enabled, i.e. secondary send
    263   // codec is registered.
    264   int ProcessDualStream();
    265 
    266   // Preprocessing of input audio, including resampling and down-mixing if
    267   // required, before pushing audio into encoder's buffer.
    268   //
    269   // in_frame: input audio-frame
    270   // ptr_out: pointer to output audio_frame. If no preprocessing is required
    271   //          |ptr_out| will be pointing to |in_frame|, otherwise pointing to
    272   //          |preprocess_frame_|.
    273   //
    274   // Return value:
    275   //   -1: if encountering an error.
    276   //    0: otherwise.
    277   int PreprocessToAddData(const AudioFrame& in_frame,
    278                           const AudioFrame** ptr_out)
    279       EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_);
    280 
    281   // Change required states after starting to receive the codec corresponding
    282   // to |index|.
    283   int UpdateUponReceivingCodec(int index);
    284 
    285   int EncodeFragmentation(int fragmentation_index,
    286                           int payload_type,
    287                           uint32_t current_timestamp,
    288                           ACMGenericCodec* encoder,
    289                           uint8_t* stream)
    290       EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_);
    291 
    292   void ResetFragmentation(int vector_size)
    293       EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_);
    294 
    295   // Get a pointer to AudioDecoder of the given codec. For some codecs, e.g.
    296   // iSAC, encoding and decoding have to be performed on a shared
    297   // codec-instance. By calling this method, we get the codec-instance that ACM
    298   // owns, then pass that to NetEq. This way, we perform both encoding and
    299   // decoding on the same codec-instance. Furthermore, ACM would have control
    300   // over decoder functionality if required. If |codec| does not share an
    301   // instance between encoder and decoder, the |*decoder| is set NULL.
    302   // The field ACMCodecDB::CodecSettings.owns_decoder indicates that if a
    303   // codec owns the decoder-instance. For such codecs |*decoder| should be a
    304   // valid pointer, otherwise it will be NULL.
    305   int GetAudioDecoder(const CodecInst& codec, int codec_id,
    306                       int mirror_id, AudioDecoder** decoder);
    307 
    308   CriticalSectionWrapper* acm_crit_sect_;
    309   int id_;  // TODO(henrik.lundin) Make const.
    310   uint32_t expected_codec_ts_ GUARDED_BY(acm_crit_sect_);
    311   uint32_t expected_in_ts_ GUARDED_BY(acm_crit_sect_);
    312   CodecInst send_codec_inst_ GUARDED_BY(acm_crit_sect_);
    313 
    314   uint8_t cng_nb_pltype_ GUARDED_BY(acm_crit_sect_);
    315   uint8_t cng_wb_pltype_ GUARDED_BY(acm_crit_sect_);
    316   uint8_t cng_swb_pltype_ GUARDED_BY(acm_crit_sect_);
    317   uint8_t cng_fb_pltype_ GUARDED_BY(acm_crit_sect_);
    318 
    319   uint8_t red_pltype_ GUARDED_BY(acm_crit_sect_);
    320   bool vad_enabled_ GUARDED_BY(acm_crit_sect_);
    321   bool dtx_enabled_ GUARDED_BY(acm_crit_sect_);
    322   ACMVADMode vad_mode_ GUARDED_BY(acm_crit_sect_);
    323   ACMGenericCodec* codecs_[ACMCodecDB::kMaxNumCodecs];
    324   int mirror_codec_idx_[ACMCodecDB::kMaxNumCodecs];
    325   bool stereo_send_ GUARDED_BY(acm_crit_sect_);
    326   int current_send_codec_idx_;
    327   bool send_codec_registered_;
    328   ACMResampler resampler_ GUARDED_BY(acm_crit_sect_);
    329   AcmReceiver receiver_;
    330 
    331   // RED.
    332   bool is_first_red_ GUARDED_BY(acm_crit_sect_);
    333   bool red_enabled_ GUARDED_BY(acm_crit_sect_);
    334 
    335   // TODO(turajs): |red_buffer_| is allocated in constructor, why having them
    336   // as pointers and not an array. If concerned about the memory, then make a
    337   // set-up function to allocate them only when they are going to be used, i.e.
    338   // RED or Dual-streaming is enabled.
    339   uint8_t* red_buffer_ GUARDED_BY(acm_crit_sect_);
    340 
    341   // TODO(turajs): we actually don't need |fragmentation_| as a member variable.
    342   // It is sufficient to keep the length & payload type of previous payload in
    343   // member variables.
    344   RTPFragmentationHeader fragmentation_ GUARDED_BY(acm_crit_sect_);
    345   uint32_t last_red_timestamp_ GUARDED_BY(acm_crit_sect_);
    346 
    347   // Codec internal FEC
    348   bool codec_fec_enabled_;
    349 
    350   // This is to keep track of CN instances where we can send DTMFs.
    351   uint8_t previous_pltype_ GUARDED_BY(acm_crit_sect_);
    352 
    353   // Used when payloads are pushed into ACM without any RTP info
    354   // One example is when pre-encoded bit-stream is pushed from
    355   // a file.
    356   // IMPORTANT: this variable is only used in IncomingPayload(), therefore,
    357   // no lock acquired when interacting with this variable. If it is going to
    358   // be used in other methods, locks need to be taken.
    359   WebRtcRTPHeader* aux_rtp_header_;
    360 
    361   bool receiver_initialized_ GUARDED_BY(acm_crit_sect_);
    362 
    363   AudioFrame preprocess_frame_ GUARDED_BY(acm_crit_sect_);
    364   CodecInst secondary_send_codec_inst_ GUARDED_BY(acm_crit_sect_);
    365   scoped_ptr<ACMGenericCodec> secondary_encoder_ GUARDED_BY(acm_crit_sect_);
    366   uint32_t codec_timestamp_ GUARDED_BY(acm_crit_sect_);
    367   bool first_10ms_data_ GUARDED_BY(acm_crit_sect_);
    368 
    369   CriticalSectionWrapper* callback_crit_sect_;
    370   AudioPacketizationCallback* packetization_callback_
    371       GUARDED_BY(callback_crit_sect_);
    372   ACMVADCallback* vad_callback_ GUARDED_BY(callback_crit_sect_);
    373 };
    374 
    375 }  // namespace acm2
    376 
    377 }  // namespace webrtc
    378 
    379 #endif  // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_AUDIO_CODING_MODULE_IMPL_H_
    380