webrtc_m130/webrtc/media/engine/webrtcvoiceengine.h
skvlad 7a43d253f9 Make the audio channel communicate network state changes to the call.
This change enables voice-only calls to keep track of the network state.
This is only a partial fix - the last modality to change state controls
the state for the entire call, so a call with a failed video transport
will also stop sending audio packets. Handling this condition correctly
would require the call to keep track of network state for each media
type separately, and take care of conditions such as a failed video
channel getting removed, while a functioning audio channel remains.

BUG=webrtc:5307

Review URL: https://codereview.webrtc.org/1757683002

Cr-Commit-Position: refs/heads/master@{#12093}
2016-03-22 22:32:31 +00:00

292 lines
10 KiB
C++

/*
* Copyright (c) 2004 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_MEDIA_ENGINE_WEBRTCVOICEENGINE_H_
#define WEBRTC_MEDIA_ENGINE_WEBRTCVOICEENGINE_H_
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "webrtc/audio_state.h"
#include "webrtc/base/buffer.h"
#include "webrtc/base/stream.h"
#include "webrtc/base/thread_checker.h"
#include "webrtc/call.h"
#include "webrtc/common.h"
#include "webrtc/config.h"
#include "webrtc/media/base/rtputils.h"
#include "webrtc/media/engine/webrtccommon.h"
#include "webrtc/media/engine/webrtcvoe.h"
#include "webrtc/pc/channel.h"
namespace cricket {
class AudioDeviceModule;
class AudioSource;
class VoEWrapper;
class WebRtcVoiceMediaChannel;
// WebRtcVoiceEngine is a class to be used with CompositeMediaEngine.
// It uses the WebRtc VoiceEngine library for audio handling.
class WebRtcVoiceEngine final : public webrtc::TraceCallback {
friend class WebRtcVoiceMediaChannel;
public:
// Exposed for the WVoE/MC unit test.
static bool ToCodecInst(const AudioCodec& in, webrtc::CodecInst* out);
WebRtcVoiceEngine();
// Dependency injection for testing.
explicit WebRtcVoiceEngine(VoEWrapper* voe_wrapper);
~WebRtcVoiceEngine();
bool Init(rtc::Thread* worker_thread);
void Terminate();
rtc::scoped_refptr<webrtc::AudioState> GetAudioState() const;
VoiceMediaChannel* CreateChannel(webrtc::Call* call,
const MediaConfig& config,
const AudioOptions& options);
bool GetOutputVolume(int* level);
bool SetOutputVolume(int level);
int GetInputLevel();
const std::vector<AudioCodec>& codecs();
RtpCapabilities GetCapabilities() const;
// For tracking WebRtc channels. Needed because we have to pause them
// all when switching devices.
// May only be called by WebRtcVoiceMediaChannel.
void RegisterChannel(WebRtcVoiceMediaChannel* channel);
void UnregisterChannel(WebRtcVoiceMediaChannel* channel);
// Called by WebRtcVoiceMediaChannel to set a gain offset from
// the default AGC target level.
bool AdjustAgcLevel(int delta);
VoEWrapper* voe() { return voe_wrapper_.get(); }
int GetLastEngineError();
// Set the external ADM. This can only be called before Init.
bool SetAudioDeviceModule(webrtc::AudioDeviceModule* adm);
// Starts AEC dump using an existing file. A maximum file size in bytes can be
// specified. When the maximum file size is reached, logging is stopped and
// the file is closed. If max_size_bytes is set to <= 0, no limit will be
// used.
bool StartAecDump(rtc::PlatformFile file, int64_t max_size_bytes);
// Stops AEC dump.
void StopAecDump();
// Starts recording an RtcEventLog using an existing file until 10 minutes
// pass or the StopRtcEventLog function is called.
bool StartRtcEventLog(rtc::PlatformFile file);
// Stops recording the RtcEventLog.
void StopRtcEventLog();
private:
void Construct();
bool InitInternal();
// Every option that is "set" will be applied. Every option not "set" will be
// ignored. This allows us to selectively turn on and off different options
// easily at any time.
bool ApplyOptions(const AudioOptions& options);
void SetDefaultDevices();
// webrtc::TraceCallback:
void Print(webrtc::TraceLevel level, const char* trace, int length) override;
void StartAecDump(const std::string& filename);
int CreateVoEChannel();
rtc::ThreadChecker signal_thread_checker_;
rtc::ThreadChecker worker_thread_checker_;
// The primary instance of WebRtc VoiceEngine.
std::unique_ptr<VoEWrapper> voe_wrapper_;
rtc::scoped_refptr<webrtc::AudioState> audio_state_;
// The external audio device manager
webrtc::AudioDeviceModule* adm_ = nullptr;
std::vector<AudioCodec> codecs_;
std::vector<WebRtcVoiceMediaChannel*> channels_;
webrtc::Config voe_config_;
bool initialized_ = false;
bool is_dumping_aec_ = false;
webrtc::AgcConfig default_agc_config_;
// Cache received extended_filter_aec, delay_agnostic_aec and experimental_ns
// values, and apply them in case they are missing in the audio options. We
// need to do this because SetExtraOptions() will revert to defaults for
// options which are not provided.
rtc::Optional<bool> extended_filter_aec_;
rtc::Optional<bool> delay_agnostic_aec_;
rtc::Optional<bool> experimental_ns_;
RTC_DISALLOW_COPY_AND_ASSIGN(WebRtcVoiceEngine);
};
// WebRtcVoiceMediaChannel is an implementation of VoiceMediaChannel that uses
// WebRtc Voice Engine.
class WebRtcVoiceMediaChannel final : public VoiceMediaChannel,
public webrtc::Transport {
public:
WebRtcVoiceMediaChannel(WebRtcVoiceEngine* engine,
const MediaConfig& config,
const AudioOptions& options,
webrtc::Call* call);
~WebRtcVoiceMediaChannel() override;
const AudioOptions& options() const { return options_; }
rtc::DiffServCodePoint PreferredDscp() const override;
bool SetSendParameters(const AudioSendParameters& params) override;
bool SetRecvParameters(const AudioRecvParameters& params) override;
bool SetPlayout(bool playout) override;
bool PausePlayout();
bool ResumePlayout();
void SetSend(bool send) override;
bool PauseSend();
bool ResumeSend();
bool SetAudioSend(uint32_t ssrc,
bool enable,
const AudioOptions* options,
AudioSource* source) override;
bool AddSendStream(const StreamParams& sp) override;
bool RemoveSendStream(uint32_t ssrc) override;
bool AddRecvStream(const StreamParams& sp) override;
bool RemoveRecvStream(uint32_t ssrc) override;
bool GetActiveStreams(AudioInfo::StreamList* actives) override;
int GetOutputLevel() override;
int GetTimeSinceLastTyping() override;
void SetTypingDetectionParameters(int time_window,
int cost_per_typing,
int reporting_threshold,
int penalty_decay,
int type_event_delay) override;
bool SetOutputVolume(uint32_t ssrc, double volume) override;
bool CanInsertDtmf() override;
bool InsertDtmf(uint32_t ssrc, int event, int duration) override;
void OnPacketReceived(rtc::CopyOnWriteBuffer* packet,
const rtc::PacketTime& packet_time) override;
void OnRtcpReceived(rtc::CopyOnWriteBuffer* packet,
const rtc::PacketTime& packet_time) override;
void OnReadyToSend(bool ready) override;
bool GetStats(VoiceMediaInfo* info) override;
void SetRawAudioSink(
uint32_t ssrc,
std::unique_ptr<webrtc::AudioSinkInterface> sink) override;
// implements Transport interface
bool SendRtp(const uint8_t* data,
size_t len,
const webrtc::PacketOptions& options) override {
rtc::CopyOnWriteBuffer packet(data, len, kMaxRtpPacketLen);
rtc::PacketOptions rtc_options;
rtc_options.packet_id = options.packet_id;
return VoiceMediaChannel::SendPacket(&packet, rtc_options);
}
bool SendRtcp(const uint8_t* data, size_t len) override {
rtc::CopyOnWriteBuffer packet(data, len, kMaxRtpPacketLen);
return VoiceMediaChannel::SendRtcp(&packet, rtc::PacketOptions());
}
int GetReceiveChannelId(uint32_t ssrc) const;
int GetSendChannelId(uint32_t ssrc) const;
private:
bool SetOptions(const AudioOptions& options);
bool SetRecvCodecs(const std::vector<AudioCodec>& codecs);
bool SetSendCodecs(const std::vector<AudioCodec>& codecs);
bool SetSendCodecs(int channel);
void SetNack(int channel, bool nack_enabled);
bool SetSendCodec(int channel, const webrtc::CodecInst& send_codec);
bool SetMaxSendBandwidth(int bps);
bool SetLocalSource(uint32_t ssrc, AudioSource* source);
bool MuteStream(uint32_t ssrc, bool mute);
WebRtcVoiceEngine* engine() { return engine_; }
int GetLastEngineError() { return engine()->GetLastEngineError(); }
int GetOutputLevel(int channel);
bool SetPlayout(int channel, bool playout);
bool ChangePlayout(bool playout);
int CreateVoEChannel();
bool DeleteVoEChannel(int channel);
bool IsDefaultRecvStream(uint32_t ssrc) {
return default_recv_ssrc_ == static_cast<int64_t>(ssrc);
}
bool SetSendBitrateInternal(int bps);
bool HasSendCodec() const {
return send_codec_spec_.codec_inst.pltype != -1;
}
rtc::ThreadChecker worker_thread_checker_;
WebRtcVoiceEngine* const engine_ = nullptr;
std::vector<AudioCodec> recv_codecs_;
bool send_bitrate_setting_ = false;
int send_bitrate_bps_ = 0;
AudioOptions options_;
rtc::Optional<int> dtmf_payload_type_;
bool desired_playout_ = false;
bool recv_transport_cc_enabled_ = false;
bool playout_ = false;
bool send_ = false;
webrtc::Call* const call_ = nullptr;
// SSRC of unsignalled receive stream, or -1 if there isn't one.
int64_t default_recv_ssrc_ = -1;
// Volume for unsignalled stream, which may be set before the stream exists.
double default_recv_volume_ = 1.0;
// Sink for unsignalled stream, which may be set before the stream exists.
std::unique_ptr<webrtc::AudioSinkInterface> default_sink_;
// Default SSRC to use for RTCP receiver reports in case of no signaled
// send streams. See: https://code.google.com/p/webrtc/issues/detail?id=4740
// and https://code.google.com/p/chromium/issues/detail?id=547661
uint32_t receiver_reports_ssrc_ = 0xFA17FA17u;
class WebRtcAudioSendStream;
std::map<uint32_t, WebRtcAudioSendStream*> send_streams_;
std::vector<webrtc::RtpExtension> send_rtp_extensions_;
class WebRtcAudioReceiveStream;
std::map<uint32_t, WebRtcAudioReceiveStream*> recv_streams_;
std::vector<webrtc::RtpExtension> recv_rtp_extensions_;
struct SendCodecSpec {
SendCodecSpec() {
webrtc::CodecInst empty_inst = {0};
codec_inst = empty_inst;
codec_inst.pltype = -1;
}
bool nack_enabled = false;
bool transport_cc_enabled = false;
bool enable_codec_fec = false;
bool enable_opus_dtx = false;
int opus_max_playback_rate = 0;
int red_payload_type = -1;
int cng_payload_type = -1;
int cng_plfreq = -1;
webrtc::CodecInst codec_inst;
} send_codec_spec_;
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcVoiceMediaChannel);
};
} // namespace cricket
#endif // WEBRTC_MEDIA_ENGINE_WEBRTCVOICEENGINE_H_