diff --git a/webrtc/modules/audio_coding/main/interface/audio_coding_module.h b/webrtc/modules/audio_coding/main/interface/audio_coding_module.h index fef4f9b55..389b93fe7 100644 --- a/webrtc/modules/audio_coding/main/interface/audio_coding_module.h +++ b/webrtc/modules/audio_coding/main/interface/audio_coding_module.h @@ -14,6 +14,7 @@ #include #include "webrtc/common_types.h" +#include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h" #include "webrtc/modules/audio_coding/main/interface/audio_coding_module_typedefs.h" #include "webrtc/modules/audio_coding/neteq/interface/neteq.h" #include "webrtc/modules/interface/module.h" @@ -998,6 +999,159 @@ class AudioCodingModule: public Module { AudioDecodingCallStats* call_stats) const = 0; }; +class AudioEncoder; +class ReceiverInfo; + +class AudioCoding { + public: + struct Config { + Config() + : neteq_config(), + clock(Clock::GetRealTimeClock()), + transport(NULL), + vad_callback(NULL), + play_dtmf(true), + initial_playout_delay_ms(0), + playout_channels(1), + playout_frequency_hz(32000) {} + + NetEq::Config neteq_config; + Clock* clock; + AudioPacketizationCallback* transport; + ACMVADCallback* vad_callback; + bool play_dtmf; + int initial_playout_delay_ms; + int playout_channels; + int playout_frequency_hz; + }; + + static AudioCoding* Create(const Config& config); + virtual ~AudioCoding() {}; + + // Registers a codec, specified by |send_codec|, as sending codec. + // This API can be called multiple times. The last codec registered overwrites + // the previous ones. Returns true if successful, false if not. + // + // Note: If a stereo codec is registered as send codec, VAD/DTX will + // automatically be turned off, since it is not supported for stereo sending. + virtual bool RegisterSendCodec(AudioEncoder* send_codec) = 0; + + // Temporary solution to be used during refactoring: + // |encoder_type| should be from the anonymous enum in acm2::ACMCodecDB. + virtual bool RegisterSendCodec(int encoder_type, + uint8_t payload_type, + int frame_size_samples = 0) = 0; + + // Returns the encoder object currently in use. This is the same as the + // codec that was registered in the latest call to RegisterSendCodec(). + virtual const AudioEncoder* GetSenderInfo() const = 0; + + // Adds 10 ms of raw (PCM) audio data to the encoder. If the sampling + // frequency of the audio does not match the sampling frequency of the + // current encoder, ACM will resample the audio. + // + // Return value: + // 0 successfully added the frame. + // -1 some error occurred and data is not added. + // < -1 to add the frame to the buffer n samples had to be + // overwritten, -n is the return value in this case. + // TODO(henrik.lundin): Make a better design for the return values. This one + // is just a copy of the old API. + virtual int Add10MsAudio(const AudioFrame& audio_frame) = 0; + + // Returns a combined info about the currently used decoder(s). + virtual const ReceiverInfo* GetReceiverInfo() const = 0; + + // Registers a codec, specified by |receive_codec|, as receiving codec. + // This API can be called multiple times. If registering with a payload type + // that was already registered in a previous call, the latest call will + // override previous calls. Returns true if successful, false if not. + virtual bool RegisterReceiveCodec(AudioDecoder* receive_codec) = 0; + + // Temporary solution: + // |decoder_type| should be from the anonymous enum in acm2::ACMCodecDB. + virtual bool RegisterReceiveCodec(int decoder_type, uint8_t payload_type) = 0; + + // The following two methods both inserts a new packet to the receiver. + // InsertPacket takes an RTP header input in |rtp_info|, while InsertPayload + // only requires a payload type and a timestamp. The latter assumes that the + // payloads come in the right order, and without any losses. In both cases, + // |incoming_payload| contains the RTP payload after the RTP header. Return + // true if successful, false if not. + virtual bool InsertPacket(const uint8_t* incoming_payload, + int32_t payload_len_bytes, + const WebRtcRTPHeader& rtp_info) = 0; + + // TODO(henrik.lundin): Remove this method? + virtual bool InsertPayload(const uint8_t* incoming_payload, + int32_t payload_len_byte, + uint8_t payload_type, + uint32_t timestamp) = 0; + + // These two methods set a minimum and maximum jitter buffer delay in + // milliseconds. The pupose is mainly to adjust the delay to synchronize + // audio and video. The preferred jitter buffer size, computed by NetEq based + // on the current channel conditions, is clamped from below and above by these + // two methods. The given delay limits must be non-negative, less than + // 10000 ms, and the minimum must be strictly smaller than the maximum. + // Further, the maximum must be at lest one frame duration. If these + // conditions are not met, false is returned. Giving the value 0 effectively + // unsets the minimum or maximum delay limits. + // Note that calling these methods is optional. If not called, NetEq will + // determine the optimal buffer size based on the network conditions. + virtual bool SetMinimumPlayoutDelay(int time_ms) = 0; + + virtual bool SetMaximumPlayoutDelay(int time_ms) = 0; + + // Returns the current value of the jitter buffer's preferred latency. This + // is computed based on inter-arrival times and playout mode of NetEq. The + // actual target delay is this value clamped from below and above by the + // values specified through SetMinimumPlayoutDelay() and + // SetMaximumPlayoutDelay(), respectively, if provided. + // TODO(henrik.lundin) Rename to PreferredDelayMs? + virtual int LeastRequiredDelayMs() const = 0; + + // The send timestamp of an RTP packet is associated with the decoded + // audio of the packet in question. This function returns the timestamp of + // the latest audio delivered by Get10MsAudio(). Returns false if no timestamp + // can be provided, true otherwise. + virtual bool PlayoutTimestamp(uint32_t* timestamp) = 0; + + // Delivers 10 ms of audio in |audio_frame|. Returns true if successful, + // false otherwise. + virtual bool Get10MsAudio(AudioFrame* audio_frame) = 0; + + // Returns the network statistics. Note that the internal statistics of NetEq + // are reset by this call. Returns true if successful, false otherwise. + virtual bool NetworkStatistics(ACMNetworkStatistics* network_statistics) = 0; + + // Enables NACK and sets the maximum size of the NACK list. If NACK is already + // enabled then the maximum NACK list size is modified accordingly. Returns + // true if successful, false otherwise. + // + // If the sequence number of last received packet is N, the sequence numbers + // of NACK list are in the range of [N - |max_nack_list_size|, N). + // + // |max_nack_list_size| should be positive and less than or equal to + // |Nack::kNackListSizeLimit|. + virtual bool EnableNack(size_t max_nack_list_size) = 0; + + // Disables NACK. + virtual void DisableNack() = 0; + + // Returns a list of packets to request retransmission of. + // |round_trip_time_ms| is an estimate of the round-trip-time (in + // milliseconds). Missing packets which will be decoded sooner than the + // round-trip-time (with respect to the time this API is called) will not be + // included in the list. + // |round_trip_time_ms| must be non-negative. + virtual std::vector GetNackList(int round_trip_time_ms) const = 0; + + // Returns the timing statistics for calls to Get10MsAudio. + virtual void GetDecodingCallStatistics( + AudioDecodingCallStats* call_stats) const = 0; +}; + } // namespace webrtc #endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_INTERFACE_AUDIO_CODING_MODULE_H_