Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1152)

Unified Diff: webrtc/media/engine/webrtcvoiceengine.cc

Issue 1841083008: WebRtcVoiceEngine refactoring - moving codec configuration code into Send/RecvStreams (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/media/engine/webrtcvoiceengine.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/media/engine/webrtcvoiceengine.cc
diff --git a/webrtc/media/engine/webrtcvoiceengine.cc b/webrtc/media/engine/webrtcvoiceengine.cc
index 6fe3d86fd98f086fe0622711c7769573d5276a1b..b00269f5f855cea0915e3739e09b0dec77b68d6d 100644
--- a/webrtc/media/engine/webrtcvoiceengine.cc
+++ b/webrtc/media/engine/webrtcvoiceengine.cc
@@ -1140,11 +1140,15 @@ int WebRtcVoiceEngine::CreateVoEChannel() {
class WebRtcVoiceMediaChannel::WebRtcAudioSendStream
: public AudioSource::Sink {
public:
- WebRtcAudioSendStream(int ch, webrtc::AudioTransport* voe_audio_transport,
- uint32_t ssrc, const std::string& c_name,
+ WebRtcAudioSendStream(int ch,
+ WebRtcVoiceEngine* engine,
the sun 2016/04/01 08:29:06 WebRtcAudioReceive/SendStream should be thin proxy
+ webrtc::AudioTransport* voe_audio_transport,
+ uint32_t ssrc,
+ const std::string& c_name,
const std::vector<webrtc::RtpExtension>& extensions,
webrtc::Call* call)
- : voe_audio_transport_(voe_audio_transport),
+ : engine_(engine),
+ voe_audio_transport_(voe_audio_transport),
call_(call),
config_(nullptr) {
RTC_DCHECK_GE(ch, 0);
@@ -1257,7 +1261,14 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream
return config_.voe_channel_id;
}
+ bool SetSendCodecs(const WebRtcVoiceMediaChannel::SendCodecSpec& spec);
+ bool SetSendCodec(const webrtc::CodecInst& send_codec);
+ void SetNack(bool nack_enabled);
+
private:
+ WebRtcVoiceEngine* engine() { return engine_; }
+ int GetLastEngineError() { return engine()->GetLastEngineError(); }
+
void UpdateSendState() {
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
RTC_DCHECK(stream_);
@@ -1270,6 +1281,7 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream
rtc::ThreadChecker worker_thread_checker_;
rtc::ThreadChecker audio_capture_thread_checker_;
+ WebRtcVoiceEngine* engine_ = nullptr;
webrtc::AudioTransport* const voe_audio_transport_ = nullptr;
webrtc::Call* call_ = nullptr;
webrtc::AudioSendStream::Config config_;
@@ -1283,19 +1295,21 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream
AudioSource* source_ = nullptr;
bool send_ = false;
+
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream);
};
class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream {
public:
WebRtcAudioReceiveStream(int ch,
+ WebRtcVoiceEngine* engine,
uint32_t remote_ssrc,
uint32_t local_ssrc,
bool use_transport_cc,
const std::string& sync_group,
const std::vector<webrtc::RtpExtension>& extensions,
webrtc::Call* call)
- : call_(call), config_() {
+ : engine_(engine), call_(call), config_() {
RTC_DCHECK_GE(ch, 0);
RTC_DCHECK(call);
config_.rtp.remote_ssrc = remote_ssrc;
@@ -1336,7 +1350,10 @@ class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream {
stream_->SetSink(std::move(sink));
}
+ void SetNack(bool nack_enabled);
+
private:
+ WebRtcVoiceEngine* engine() { return engine_; }
void RecreateAudioReceiveStream(
bool use_transport_cc,
const std::vector<webrtc::RtpExtension>& extensions) {
@@ -1353,6 +1370,7 @@ class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream {
}
rtc::ThreadChecker worker_thread_checker_;
+ WebRtcVoiceEngine* engine_ = nullptr;
webrtc::Call* call_ = nullptr;
webrtc::AudioReceiveStream::Config config_;
// The stream is owned by WebRtcAudioReceiveStream and may be reallocated if
@@ -1646,15 +1664,19 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs(
// Cache the codecs in order to configure the channel created later.
for (const auto& ch : send_streams_) {
- if (!SetSendCodecs(ch.second->channel())) {
+ if (!ch.second->SetSendCodecs(send_codec_spec_)) {
return false;
}
}
+ if (send_bitrate_setting_) {
+ SetSendBitrateInternal(send_bitrate_bps_);
+ }
+
// Set nack status on receive channels.
if (!send_streams_.empty()) {
for (const auto& kv : recv_streams_) {
- SetNack(kv.second->channel(), send_codec_spec_.nack_enabled);
+ kv.second->SetNack(send_codec_spec_.nack_enabled);
}
}
@@ -1672,156 +1694,6 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs(
return true;
}
-// Apply current codec settings to a single voe::Channel used for sending.
-bool WebRtcVoiceMediaChannel::SetSendCodecs(int channel) {
- // Disable VAD, FEC, and RED unless we know the other side wants them.
- engine()->voe()->codec()->SetVADStatus(channel, false);
- engine()->voe()->rtp()->SetNACKStatus(channel, false, 0);
- engine()->voe()->rtp()->SetREDStatus(channel, false);
- engine()->voe()->codec()->SetFECStatus(channel, false);
-
- if (send_codec_spec_.red_payload_type != -1) {
- // Enable redundant encoding of the specified codec. Treat any
- // failure as a fatal internal error.
- LOG(LS_INFO) << "Enabling RED on channel " << channel;
- if (engine()->voe()->rtp()->SetREDStatus(channel, true,
- send_codec_spec_.red_payload_type) == -1) {
- LOG_RTCERR3(SetREDStatus, channel, true,
- send_codec_spec_.red_payload_type);
- return false;
- }
- }
-
- SetNack(channel, send_codec_spec_.nack_enabled);
-
- // Set the codec immediately, since SetVADStatus() depends on whether
- // the current codec is mono or stereo.
- if (!SetSendCodec(channel, send_codec_spec_.codec_inst)) {
- return false;
- }
-
- // FEC should be enabled after SetSendCodec.
- if (send_codec_spec_.enable_codec_fec) {
- LOG(LS_INFO) << "Attempt to enable codec internal FEC on channel "
- << channel;
- if (engine()->voe()->codec()->SetFECStatus(channel, true) == -1) {
- // Enable codec internal FEC. Treat any failure as fatal internal error.
- LOG_RTCERR2(SetFECStatus, channel, true);
- return false;
- }
- }
-
- if (IsCodec(send_codec_spec_.codec_inst, kOpusCodecName)) {
- // DTX and maxplaybackrate should be set after SetSendCodec. Because current
- // send codec has to be Opus.
-
- // Set Opus internal DTX.
- LOG(LS_INFO) << "Attempt to "
- << (send_codec_spec_.enable_opus_dtx ? "enable" : "disable")
- << " Opus DTX on channel "
- << channel;
- if (engine()->voe()->codec()->SetOpusDtx(channel,
- send_codec_spec_.enable_opus_dtx)) {
- LOG_RTCERR2(SetOpusDtx, channel, send_codec_spec_.enable_opus_dtx);
- return false;
- }
-
- // If opus_max_playback_rate <= 0, the default maximum playback rate
- // (48 kHz) will be used.
- if (send_codec_spec_.opus_max_playback_rate > 0) {
- LOG(LS_INFO) << "Attempt to set maximum playback rate to "
- << send_codec_spec_.opus_max_playback_rate
- << " Hz on channel "
- << channel;
- if (engine()->voe()->codec()->SetOpusMaxPlaybackRate(
- channel, send_codec_spec_.opus_max_playback_rate) == -1) {
- LOG_RTCERR2(SetOpusMaxPlaybackRate, channel,
- send_codec_spec_.opus_max_playback_rate);
- return false;
- }
- }
- }
-
- if (send_bitrate_setting_) {
- SetSendBitrateInternal(send_bitrate_bps_);
- }
-
- // Set the CN payloadtype and the VAD status.
- if (send_codec_spec_.cng_payload_type != -1) {
- // The CN payload type for 8000 Hz clockrate is fixed at 13.
- if (send_codec_spec_.cng_plfreq != 8000) {
- webrtc::PayloadFrequencies cn_freq;
- switch (send_codec_spec_.cng_plfreq) {
- case 16000:
- cn_freq = webrtc::kFreq16000Hz;
- break;
- case 32000:
- cn_freq = webrtc::kFreq32000Hz;
- break;
- default:
- RTC_NOTREACHED();
- return false;
- }
- if (engine()->voe()->codec()->SetSendCNPayloadType(
- channel, send_codec_spec_.cng_payload_type, cn_freq) == -1) {
- LOG_RTCERR3(SetSendCNPayloadType, channel,
- send_codec_spec_.cng_payload_type, cn_freq);
- // TODO(ajm): This failure condition will be removed from VoE.
- // Restore the return here when we update to a new enough webrtc.
- //
- // Not returning false because the SetSendCNPayloadType will fail if
- // the channel is already sending.
- // This can happen if the remote description is applied twice, for
- // example in the case of ROAP on top of JSEP, where both side will
- // send the offer.
- }
- }
-
- // Only turn on VAD if we have a CN payload type that matches the
- // clockrate for the codec we are going to use.
- if (send_codec_spec_.cng_plfreq == send_codec_spec_.codec_inst.plfreq &&
- send_codec_spec_.codec_inst.channels == 1) {
- // TODO(minyue): If CN frequency == 48000 Hz is allowed, consider the
- // interaction between VAD and Opus FEC.
- LOG(LS_INFO) << "Enabling VAD";
- if (engine()->voe()->codec()->SetVADStatus(channel, true) == -1) {
- LOG_RTCERR2(SetVADStatus, channel, true);
- return false;
- }
- }
- }
- return true;
-}
-
-void WebRtcVoiceMediaChannel::SetNack(int channel, bool nack_enabled) {
- if (nack_enabled) {
- LOG(LS_INFO) << "Enabling NACK for channel " << channel;
- engine()->voe()->rtp()->SetNACKStatus(channel, true, kNackMaxPackets);
- } else {
- LOG(LS_INFO) << "Disabling NACK for channel " << channel;
- engine()->voe()->rtp()->SetNACKStatus(channel, false, 0);
- }
-}
-
-bool WebRtcVoiceMediaChannel::SetSendCodec(
- int channel, const webrtc::CodecInst& send_codec) {
- LOG(LS_INFO) << "Send channel " << channel << " selected voice codec "
- << ToString(send_codec) << ", bitrate=" << send_codec.rate;
-
- webrtc::CodecInst current_codec = {0};
- if (engine()->voe()->codec()->GetSendCodec(channel, current_codec) == 0 &&
- (send_codec == current_codec)) {
- // Codec is already configured, we can return without setting it again.
- return true;
- }
-
- if (engine()->voe()->codec()->SetSendCodec(channel, send_codec) == -1) {
- LOG_RTCERR2(SetSendCodec, channel, ToString(send_codec));
- return false;
- }
- return true;
-}
-
bool WebRtcVoiceMediaChannel::SetPlayout(bool playout) {
desired_playout_ = playout;
return ChangePlayout(desired_playout_);
@@ -1939,17 +1811,23 @@ bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) {
// delete the channel in case failure happens below.
webrtc::AudioTransport* audio_transport =
engine()->voe()->base()->audio_transport();
- send_streams_.insert(std::make_pair(ssrc, new WebRtcAudioSendStream(
- channel, audio_transport, ssrc, sp.cname, send_rtp_extensions_, call_)));
+ WebRtcAudioSendStream* send_stream =
+ new WebRtcAudioSendStream(channel, engine(), audio_transport, ssrc,
+ sp.cname, send_rtp_extensions_, call_);
+ send_streams_.insert(std::make_pair(ssrc, send_stream));
// Set the current codecs to be used for the new channel. We need to do this
// after adding the channel to send_channels_, because of how max bitrate is
// currently being configured by SetSendCodec().
- if (HasSendCodec() && !SetSendCodecs(channel)) {
+ if (HasSendCodec() && !send_stream->SetSendCodecs(send_codec_spec_)) {
RemoveSendStream(ssrc);
return false;
}
+ if (send_bitrate_setting_) {
+ SetSendBitrateInternal(send_bitrate_bps_);
+ }
+
// At this point the channel's local SSRC has been updated. If the channel is
// the first send channel make sure that all the receive channels are updated
// with the same SSRC in order to send receiver reports.
@@ -2066,13 +1944,12 @@ bool WebRtcVoiceMediaChannel::AddRecvStream(const StreamParams& sp) {
<< " is associated with channel #" << send_channel << ".";
}
- recv_streams_.insert(std::make_pair(
- ssrc, new WebRtcAudioReceiveStream(channel, ssrc, receiver_reports_ssrc_,
- recv_transport_cc_enabled_,
- sp.sync_label, recv_rtp_extensions_,
- call_)));
+ WebRtcAudioReceiveStream* recv_stream = new WebRtcAudioReceiveStream(
+ channel, engine(), ssrc, receiver_reports_ssrc_,
+ recv_transport_cc_enabled_, sp.sync_label, recv_rtp_extensions_, call_);
+ recv_streams_.insert(std::make_pair(ssrc, recv_stream));
- SetNack(channel, send_codec_spec_.nack_enabled);
+ recv_stream->SetNack(send_codec_spec_.nack_enabled);
SetPlayout(channel, playout_);
return true;
@@ -2401,7 +2278,7 @@ bool WebRtcVoiceMediaChannel::SetSendBitrateInternal(int bps) {
// If codec is multi-rate then just set the bitrate.
codec.rate = bps;
for (const auto& ch : send_streams_) {
- if (!SetSendCodec(ch.second->channel(), codec)) {
+ if (!ch.second->SetSendCodec(codec)) {
LOG(LS_INFO) << "Failed to set codec " << codec.plname
<< " to bitrate " << bps << " bps.";
return false;
@@ -2555,6 +2432,164 @@ bool WebRtcVoiceMediaChannel::SetPlayout(int channel, bool playout) {
}
return true;
}
+
+// Apply current codec settings to a single voe::Channel used for sending.
+bool WebRtcVoiceMediaChannel::WebRtcAudioSendStream::SetSendCodecs(
+ const WebRtcVoiceMediaChannel::SendCodecSpec& send_codec_spec) {
+ // Disable VAD, FEC, and RED unless we know the other side wants them.
+ engine()->voe()->codec()->SetVADStatus(channel(), false);
+ engine()->voe()->rtp()->SetNACKStatus(channel(), false, 0);
+ engine()->voe()->rtp()->SetREDStatus(channel(), false);
+ engine()->voe()->codec()->SetFECStatus(channel(), false);
+
+ if (send_codec_spec.red_payload_type != -1) {
+ // Enable redundant encoding of the specified codec. Treat any
+ // failure as a fatal internal error.
+ LOG(LS_INFO) << "Enabling RED on channel " << channel();
+ if (engine()->voe()->rtp()->SetREDStatus(
+ channel(), true, send_codec_spec.red_payload_type) == -1) {
+ LOG_RTCERR3(SetREDStatus, channel(), true,
+ send_codec_spec.red_payload_type);
+ return false;
+ }
+ }
+
+ SetNack(send_codec_spec.nack_enabled);
+
+ // Set the codec immediately, since SetVADStatus() depends on whether
+ // the current codec is mono or stereo.
+ if (!SetSendCodec(send_codec_spec.codec_inst)) {
+ return false;
+ }
+
+ // FEC should be enabled after SetSendCodec.
+ if (send_codec_spec.enable_codec_fec) {
+ LOG(LS_INFO) << "Attempt to enable codec internal FEC on channel "
+ << channel();
+ if (engine()->voe()->codec()->SetFECStatus(channel(), true) == -1) {
+ // Enable codec internal FEC. Treat any failure as fatal internal error.
+ LOG_RTCERR2(SetFECStatus, channel(), true);
+ return false;
+ }
+ }
+
+ if (IsCodec(send_codec_spec.codec_inst, kOpusCodecName)) {
+ // DTX and maxplaybackrate should be set after SetSendCodec. Because current
+ // send codec has to be Opus.
+
+ // Set Opus internal DTX.
+ LOG(LS_INFO) << "Attempt to "
+ << (send_codec_spec.enable_opus_dtx ? "enable" : "disable")
+ << " Opus DTX on channel " << channel();
+ if (engine()->voe()->codec()->SetOpusDtx(
+ channel(), send_codec_spec.enable_opus_dtx)) {
+ LOG_RTCERR2(SetOpusDtx, channel(), send_codec_spec.enable_opus_dtx);
+ return false;
+ }
+
+ // If opus_max_playback_rate <= 0, the default maximum playback rate
+ // (48 kHz) will be used.
+ if (send_codec_spec.opus_max_playback_rate > 0) {
+ LOG(LS_INFO) << "Attempt to set maximum playback rate to "
+ << send_codec_spec.opus_max_playback_rate
+ << " Hz on channel " << channel();
+ if (engine()->voe()->codec()->SetOpusMaxPlaybackRate(
+ channel(), send_codec_spec.opus_max_playback_rate) == -1) {
+ LOG_RTCERR2(SetOpusMaxPlaybackRate, channel(),
+ send_codec_spec.opus_max_playback_rate);
+ return false;
+ }
+ }
+ }
+
+ // Set the CN payloadtype and the VAD status.
+ if (send_codec_spec.cng_payload_type != -1) {
+ // The CN payload type for 8000 Hz clockrate is fixed at 13.
+ if (send_codec_spec.cng_plfreq != 8000) {
+ webrtc::PayloadFrequencies cn_freq;
+ switch (send_codec_spec.cng_plfreq) {
+ case 16000:
+ cn_freq = webrtc::kFreq16000Hz;
+ break;
+ case 32000:
+ cn_freq = webrtc::kFreq32000Hz;
+ break;
+ default:
+ RTC_NOTREACHED();
+ return false;
+ }
+ if (engine()->voe()->codec()->SetSendCNPayloadType(
+ channel(), send_codec_spec.cng_payload_type, cn_freq) == -1) {
+ LOG_RTCERR3(SetSendCNPayloadType, channel(),
+ send_codec_spec.cng_payload_type, cn_freq);
+ // TODO(ajm): This failure condition will be removed from VoE.
+ // Restore the return here when we update to a new enough webrtc.
+ //
+ // Not returning false because the SetSendCNPayloadType will fail if
+ // the channel is already sending.
+ // This can happen if the remote description is applied twice, for
+ // example in the case of ROAP on top of JSEP, where both side will
+ // send the offer.
+ }
+ }
+
+ // Only turn on VAD if we have a CN payload type that matches the
+ // clockrate for the codec we are going to use.
+ if (send_codec_spec.cng_plfreq == send_codec_spec.codec_inst.plfreq &&
+ send_codec_spec.codec_inst.channels == 1) {
+ // TODO(minyue): If CN frequency == 48000 Hz is allowed, consider the
+ // interaction between VAD and Opus FEC.
+ LOG(LS_INFO) << "Enabling VAD";
+ if (engine()->voe()->codec()->SetVADStatus(channel(), true) == -1) {
+ LOG_RTCERR2(SetVADStatus, channel(), true);
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+bool WebRtcVoiceMediaChannel::WebRtcAudioSendStream::SetSendCodec(
+ const webrtc::CodecInst& send_codec) {
+ LOG(LS_INFO) << "Send channel " << channel() << " selected voice codec "
+ << ToString(send_codec) << ", bitrate=" << send_codec.rate;
+
+ webrtc::CodecInst current_codec = {0};
+ if (engine()->voe()->codec()->GetSendCodec(channel(), current_codec) == 0 &&
+ (send_codec == current_codec)) {
+ // Codec is already configured, we can return without setting it again.
+ return true;
+ }
+
+ if (engine()->voe()->codec()->SetSendCodec(channel(), send_codec) == -1) {
+ LOG_RTCERR2(SetSendCodec, channel(), ToString(send_codec));
+ return false;
+ }
+ return true;
+}
+
+void WebRtcVoiceMediaChannel::WebRtcAudioSendStream::SetNack(
+ bool nack_enabled) {
+ if (nack_enabled) {
+ LOG(LS_INFO) << "Enabling NACK for channel " << channel();
+ engine()->voe()->rtp()->SetNACKStatus(channel(), true, kNackMaxPackets);
+ } else {
+ LOG(LS_INFO) << "Disabling NACK for channel " << channel();
+ engine()->voe()->rtp()->SetNACKStatus(channel(), false, 0);
+ }
+}
+
+void WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream::SetNack(
+ bool nack_enabled) {
+ if (nack_enabled) {
+ LOG(LS_INFO) << "Enabling NACK for channel " << channel();
+ engine()->voe()->rtp()->SetNACKStatus(channel(), true, kNackMaxPackets);
+ } else {
+ LOG(LS_INFO) << "Disabling NACK for channel " << channel();
+ engine()->voe()->rtp()->SetNACKStatus(channel(), false, 0);
+ }
+}
+
} // namespace cricket
#endif // HAVE_WEBRTC_VOICE
« no previous file with comments | « webrtc/media/engine/webrtcvoiceengine.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698