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

Side by Side Diff: talk/media/webrtc/webrtcvoiceengine.cc

Issue 1461333002: Using Rent-A-Codec for static Codec access in WVoE/MC. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: rebase Created 5 years 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 unified diff | Download patch
« no previous file with comments | « talk/media/webrtc/webrtcvoiceengine.h ('k') | talk/media/webrtc/webrtcvoiceengine_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * libjingle 2 * libjingle
3 * Copyright 2004 Google Inc. 3 * Copyright 2004 Google Inc.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright notice, 8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer. 9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 #include "webrtc/base/arraysize.h" 46 #include "webrtc/base/arraysize.h"
47 #include "webrtc/base/base64.h" 47 #include "webrtc/base/base64.h"
48 #include "webrtc/base/byteorder.h" 48 #include "webrtc/base/byteorder.h"
49 #include "webrtc/base/common.h" 49 #include "webrtc/base/common.h"
50 #include "webrtc/base/helpers.h" 50 #include "webrtc/base/helpers.h"
51 #include "webrtc/base/logging.h" 51 #include "webrtc/base/logging.h"
52 #include "webrtc/base/stringencode.h" 52 #include "webrtc/base/stringencode.h"
53 #include "webrtc/base/stringutils.h" 53 #include "webrtc/base/stringutils.h"
54 #include "webrtc/call/rtc_event_log.h" 54 #include "webrtc/call/rtc_event_log.h"
55 #include "webrtc/common.h" 55 #include "webrtc/common.h"
56 #include "webrtc/modules/audio_coding/acm2/rent_a_codec.h"
56 #include "webrtc/modules/audio_processing/include/audio_processing.h" 57 #include "webrtc/modules/audio_processing/include/audio_processing.h"
57 #include "webrtc/system_wrappers/include/field_trial.h" 58 #include "webrtc/system_wrappers/include/field_trial.h"
58 #include "webrtc/system_wrappers/include/trace.h" 59 #include "webrtc/system_wrappers/include/trace.h"
59 60
60 namespace cricket { 61 namespace cricket {
61 namespace { 62 namespace {
62 63
63 const int kDefaultTraceFilter = webrtc::kTraceNone | webrtc::kTraceTerseInfo | 64 const int kDefaultTraceFilter = webrtc::kTraceNone | webrtc::kTraceTerseInfo |
64 webrtc::kTraceWarning | webrtc::kTraceError | 65 webrtc::kTraceWarning | webrtc::kTraceError |
65 webrtc::kTraceCritical; 66 webrtc::kTraceCritical;
66 const int kElevatedTraceFilter = kDefaultTraceFilter | webrtc::kTraceStateInfo | 67 const int kElevatedTraceFilter = kDefaultTraceFilter | webrtc::kTraceStateInfo |
67 webrtc::kTraceInfo; 68 webrtc::kTraceInfo;
68 69
69 const int kMaxNumPacketSize = 6;
70 struct CodecPref {
71 const char* name;
72 int clockrate;
73 int channels;
74 int payload_type;
75 bool is_multi_rate;
76 int packet_sizes_ms[kMaxNumPacketSize];
77 };
78 // Note: keep the supported packet sizes in ascending order.
79 const CodecPref kCodecPrefs[] = {
80 { kOpusCodecName, 48000, 2, 111, true, { 10, 20, 40, 60 } },
81 { kIsacCodecName, 16000, 1, 103, true, { 30, 60 } },
82 { kIsacCodecName, 32000, 1, 104, true, { 30 } },
83 // G722 should be advertised as 8000 Hz because of the RFC "bug".
84 { kG722CodecName, 8000, 1, 9, false, { 10, 20, 30, 40, 50, 60 } },
85 { kIlbcCodecName, 8000, 1, 102, false, { 20, 30, 40, 60 } },
86 { kPcmuCodecName, 8000, 1, 0, false, { 10, 20, 30, 40, 50, 60 } },
87 { kPcmaCodecName, 8000, 1, 8, false, { 10, 20, 30, 40, 50, 60 } },
88 { kCnCodecName, 32000, 1, 106, false, { } },
89 { kCnCodecName, 16000, 1, 105, false, { } },
90 { kCnCodecName, 8000, 1, 13, false, { } },
91 { kRedCodecName, 8000, 1, 127, false, { } },
92 { kDtmfCodecName, 8000, 1, 126, false, { } },
93 };
94
95 // For Linux/Mac, using the default device is done by specifying index 0 for 70 // For Linux/Mac, using the default device is done by specifying index 0 for
96 // VoE 4.0 and not -1 (which was the case for VoE 3.5). 71 // VoE 4.0 and not -1 (which was the case for VoE 3.5).
97 // 72 //
98 // On Windows Vista and newer, Microsoft introduced the concept of "Default 73 // On Windows Vista and newer, Microsoft introduced the concept of "Default
99 // Communications Device". This means that there are two types of default 74 // Communications Device". This means that there are two types of default
100 // devices (old Wave Audio style default and Default Communications Device). 75 // devices (old Wave Audio style default and Default Communications Device).
101 // 76 //
102 // On Windows systems which only support Wave Audio style default, uses either 77 // On Windows systems which only support Wave Audio style default, uses either
103 // -1 or 0 to select the default device. 78 // -1 or 0 to select the default device.
104 // 79 //
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 return ss.str(); 153 return ss.str();
179 } 154 }
180 155
181 std::string ToString(const webrtc::CodecInst& codec) { 156 std::string ToString(const webrtc::CodecInst& codec) {
182 std::stringstream ss; 157 std::stringstream ss;
183 ss << codec.plname << "/" << codec.plfreq << "/" << codec.channels 158 ss << codec.plname << "/" << codec.plfreq << "/" << codec.channels
184 << " (" << codec.pltype << ")"; 159 << " (" << codec.pltype << ")";
185 return ss.str(); 160 return ss.str();
186 } 161 }
187 162
188 void LogMultiline(rtc::LoggingSeverity sev, char* text) {
189 const char* delim = "\r\n";
190 for (char* tok = strtok(text, delim); tok; tok = strtok(NULL, delim)) {
191 LOG_V(sev) << tok;
192 }
193 }
194
195 bool IsCodec(const AudioCodec& codec, const char* ref_name) { 163 bool IsCodec(const AudioCodec& codec, const char* ref_name) {
196 return (_stricmp(codec.name.c_str(), ref_name) == 0); 164 return (_stricmp(codec.name.c_str(), ref_name) == 0);
197 } 165 }
198 166
199 bool IsCodec(const webrtc::CodecInst& codec, const char* ref_name) { 167 bool IsCodec(const webrtc::CodecInst& codec, const char* ref_name) {
200 return (_stricmp(codec.plname, ref_name) == 0); 168 return (_stricmp(codec.plname, ref_name) == 0);
201 } 169 }
202 170
203 bool IsCodecMultiRate(const webrtc::CodecInst& codec) {
204 for (size_t i = 0; i < arraysize(kCodecPrefs); ++i) {
205 if (IsCodec(codec, kCodecPrefs[i].name) &&
206 kCodecPrefs[i].clockrate == codec.plfreq) {
207 return kCodecPrefs[i].is_multi_rate;
208 }
209 }
210 return false;
211 }
212
213 bool FindCodec(const std::vector<AudioCodec>& codecs, 171 bool FindCodec(const std::vector<AudioCodec>& codecs,
214 const AudioCodec& codec, 172 const AudioCodec& codec,
215 AudioCodec* found_codec) { 173 AudioCodec* found_codec) {
216 for (const AudioCodec& c : codecs) { 174 for (const AudioCodec& c : codecs) {
217 if (c.Matches(codec)) { 175 if (c.Matches(codec)) {
218 if (found_codec != NULL) { 176 if (found_codec != NULL) {
219 *found_codec = c; 177 *found_codec = c;
220 } 178 }
221 return true; 179 return true;
222 } 180 }
223 } 181 }
224 return false; 182 return false;
225 } 183 }
226 184
227 bool VerifyUniquePayloadTypes(const std::vector<AudioCodec>& codecs) { 185 bool VerifyUniquePayloadTypes(const std::vector<AudioCodec>& codecs) {
228 if (codecs.empty()) { 186 if (codecs.empty()) {
229 return true; 187 return true;
230 } 188 }
231 std::vector<int> payload_types; 189 std::vector<int> payload_types;
232 for (const AudioCodec& codec : codecs) { 190 for (const AudioCodec& codec : codecs) {
233 payload_types.push_back(codec.id); 191 payload_types.push_back(codec.id);
234 } 192 }
235 std::sort(payload_types.begin(), payload_types.end()); 193 std::sort(payload_types.begin(), payload_types.end());
236 auto it = std::unique(payload_types.begin(), payload_types.end()); 194 auto it = std::unique(payload_types.begin(), payload_types.end());
237 return it == payload_types.end(); 195 return it == payload_types.end();
238 } 196 }
239 197
240 bool IsNackEnabled(const AudioCodec& codec) { 198 bool IsNackEnabled(const AudioCodec& codec) {
241 return codec.HasFeedbackParam(FeedbackParam(kRtcpFbParamNack, 199 return codec.HasFeedbackParam(FeedbackParam(kRtcpFbParamNack,
242 kParamValueEmpty)); 200 kParamValueEmpty));
243 } 201 }
244 202
245 int SelectPacketSize(const CodecPref& codec_pref, int ptime_ms) {
246 int selected_packet_size_ms = codec_pref.packet_sizes_ms[0];
247 for (int packet_size_ms : codec_pref.packet_sizes_ms) {
248 if (packet_size_ms && packet_size_ms <= ptime_ms) {
249 selected_packet_size_ms = packet_size_ms;
250 }
251 }
252 return selected_packet_size_ms;
253 }
254
255 // If the AudioCodec param kCodecParamPTime is set, then we will set it to codec
256 // pacsize if it's valid, or we will pick the next smallest value we support.
257 // TODO(Brave): Query supported packet sizes from ACM when the API is ready.
258 bool SetPTimeAsPacketSize(webrtc::CodecInst* codec, int ptime_ms) {
259 for (const CodecPref& codec_pref : kCodecPrefs) {
260 if ((IsCodec(*codec, codec_pref.name) &&
261 codec_pref.clockrate == codec->plfreq) ||
262 IsCodec(*codec, kG722CodecName)) {
263 int packet_size_ms = SelectPacketSize(codec_pref, ptime_ms);
264 if (packet_size_ms) {
265 // Convert unit from milli-seconds to samples.
266 codec->pacsize = (codec->plfreq / 1000) * packet_size_ms;
267 return true;
268 }
269 }
270 }
271 return false;
272 }
273
274 // Return true if codec.params[feature] == "1", false otherwise. 203 // Return true if codec.params[feature] == "1", false otherwise.
275 bool IsCodecFeatureEnabled(const AudioCodec& codec, 204 bool IsCodecFeatureEnabled(const AudioCodec& codec, const char* feature) {
276 const char* feature) {
277 int value; 205 int value;
278 return codec.GetParam(feature, &value) && value == 1; 206 return codec.GetParam(feature, &value) && value == 1;
279 } 207 }
280 208
281 // Use params[kCodecParamMaxAverageBitrate] if it is defined, use codec.bitrate 209 // Use params[kCodecParamMaxAverageBitrate] if it is defined, use codec.bitrate
282 // otherwise. If the value (either from params or codec.bitrate) <=0, use the 210 // otherwise. If the value (either from params or codec.bitrate) <=0, use the
283 // default configuration. If the value is beyond feasible bit rate of Opus, 211 // default configuration. If the value is beyond feasible bit rate of Opus,
284 // clamp it. Returns the Opus bit rate for operation. 212 // clamp it. Returns the Opus bit rate for operation.
285 int GetOpusBitrate(const AudioCodec& codec, int max_playback_rate) { 213 int GetOpusBitrate(const AudioCodec& codec, int max_playback_rate) {
286 int bitrate = 0; 214 int bitrate = 0;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 // If OPUS, change what we send according to the "stereo" codec 261 // If OPUS, change what we send according to the "stereo" codec
334 // parameter, and not the "channels" parameter. We set 262 // parameter, and not the "channels" parameter. We set
335 // voe_codec.channels to 2 if "stereo=1" and 1 otherwise. If 263 // voe_codec.channels to 2 if "stereo=1" and 1 otherwise. If
336 // the bitrate is not specified, i.e. is <= zero, we set it to the 264 // the bitrate is not specified, i.e. is <= zero, we set it to the
337 // appropriate default value for mono or stereo Opus. 265 // appropriate default value for mono or stereo Opus.
338 266
339 voe_codec->channels = IsCodecFeatureEnabled(codec, kCodecParamStereo) ? 2 : 1; 267 voe_codec->channels = IsCodecFeatureEnabled(codec, kCodecParamStereo) ? 2 : 1;
340 voe_codec->rate = GetOpusBitrate(codec, *max_playback_rate); 268 voe_codec->rate = GetOpusBitrate(codec, *max_playback_rate);
341 } 269 }
342 270
343 // Changes RTP timestamp rate of G722. This is due to the "bug" in the RFC
344 // which says that G722 should be advertised as 8 kHz although it is a 16 kHz
345 // codec.
346 void MaybeFixupG722(webrtc::CodecInst* voe_codec, int new_plfreq) {
347 if (IsCodec(*voe_codec, kG722CodecName)) {
348 // If the ASSERT triggers, the codec definition in WebRTC VoiceEngine
349 // has changed, and this special case is no longer needed.
350 RTC_DCHECK(voe_codec->plfreq != new_plfreq);
351 voe_codec->plfreq = new_plfreq;
352 }
353 }
354
355 // Gets the default set of options applied to the engine. Historically, these 271 // Gets the default set of options applied to the engine. Historically, these
356 // were supplied as a combination of flags from the channel manager (ec, agc, 272 // were supplied as a combination of flags from the channel manager (ec, agc,
357 // ns, and highpass) and the rest hardcoded in InitInternal. 273 // ns, and highpass) and the rest hardcoded in InitInternal.
358 AudioOptions GetDefaultEngineOptions() { 274 AudioOptions GetDefaultEngineOptions() {
359 AudioOptions options; 275 AudioOptions options;
360 options.echo_cancellation = rtc::Optional<bool>(true); 276 options.echo_cancellation = rtc::Optional<bool>(true);
361 options.auto_gain_control = rtc::Optional<bool>(true); 277 options.auto_gain_control = rtc::Optional<bool>(true);
362 options.noise_suppression = rtc::Optional<bool>(true); 278 options.noise_suppression = rtc::Optional<bool>(true);
363 options.highpass_filter = rtc::Optional<bool>(true); 279 options.highpass_filter = rtc::Optional<bool>(true);
364 options.stereo_swapping = rtc::Optional<bool>(false); 280 options.stereo_swapping = rtc::Optional<bool>(false);
(...skipping 21 matching lines...) Expand all
386 for (const auto& extension : extensions) { 302 for (const auto& extension : extensions) {
387 if (extension.uri == kRtpAbsoluteSenderTimeHeaderExtension || 303 if (extension.uri == kRtpAbsoluteSenderTimeHeaderExtension ||
388 extension.uri == kRtpAudioLevelHeaderExtension) { 304 extension.uri == kRtpAudioLevelHeaderExtension) {
389 result.push_back({extension.uri, extension.id}); 305 result.push_back({extension.uri, extension.id});
390 } else { 306 } else {
391 LOG(LS_WARNING) << "Unsupported RTP extension: " << extension.ToString(); 307 LOG(LS_WARNING) << "Unsupported RTP extension: " << extension.ToString();
392 } 308 }
393 } 309 }
394 return result; 310 return result;
395 } 311 }
396 } // namespace {
397 312
398 WebRtcVoiceEngine::WebRtcVoiceEngine() 313 class WebRtcVoiceCodecs final {
399 : voe_wrapper_(new VoEWrapper()), 314 public:
400 audio_state_(webrtc::AudioState::Create(MakeAudioStateConfig(voe()))) { 315 // TODO(solenberg): Do this filtering once off-line, add a simple AudioCodec
401 Construct(); 316 // list and add a test which verifies VoE supports the listed codecs.
402 } 317 static std::vector<AudioCodec> SupportedCodecs() {
403 318 LOG(LS_INFO) << "WebRtc VoiceEngine codecs:";
404 WebRtcVoiceEngine::WebRtcVoiceEngine(VoEWrapper* voe_wrapper) 319 std::vector<AudioCodec> result;
405 : voe_wrapper_(voe_wrapper) { 320 for (webrtc::CodecInst voe_codec : webrtc::acm2::RentACodec::Database()) {
406 Construct(); 321 // Change the sample rate of G722 to 8000 to match SDP.
407 } 322 MaybeFixupG722(&voe_codec, 8000);
408
409 void WebRtcVoiceEngine::Construct() {
410 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
411 LOG(LS_VERBOSE) << "WebRtcVoiceEngine::WebRtcVoiceEngine";
412
413 signal_thread_checker_.DetachFromThread();
414 std::memset(&default_agc_config_, 0, sizeof(default_agc_config_));
415
416 webrtc::Trace::set_level_filter(kDefaultTraceFilter);
417 webrtc::Trace::SetTraceCallback(this);
418
419 // Load our audio codec list.
420 ConstructCodecs();
421
422 // Load our RTP Header extensions.
423 rtp_header_extensions_.push_back(
424 RtpHeaderExtension(kRtpAudioLevelHeaderExtension,
425 kRtpAudioLevelHeaderExtensionDefaultId));
426 rtp_header_extensions_.push_back(
427 RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension,
428 kRtpAbsoluteSenderTimeHeaderExtensionDefaultId));
429 if (webrtc::field_trial::FindFullName("WebRTC-SendSideBwe") == "Enabled") {
430 rtp_header_extensions_.push_back(RtpHeaderExtension(
431 kRtpTransportSequenceNumberHeaderExtension,
432 kRtpTransportSequenceNumberHeaderExtensionDefaultId));
433 }
434 options_ = GetDefaultEngineOptions();
435 }
436
437 void WebRtcVoiceEngine::ConstructCodecs() {
438 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
439 LOG(LS_INFO) << "WebRtc VoiceEngine codecs:";
440 int ncodecs = voe_wrapper_->codec()->NumOfCodecs();
441 for (int i = 0; i < ncodecs; ++i) {
442 webrtc::CodecInst voe_codec;
443 if (GetVoeCodec(i, &voe_codec)) {
444 // Skip uncompressed formats. 323 // Skip uncompressed formats.
445 if (IsCodec(voe_codec, kL16CodecName)) { 324 if (IsCodec(voe_codec, kL16CodecName)) {
446 continue; 325 continue;
447 } 326 }
448 327
449 const CodecPref* pref = NULL; 328 const CodecPref* pref = NULL;
450 for (size_t j = 0; j < arraysize(kCodecPrefs); ++j) { 329 for (size_t j = 0; j < arraysize(kCodecPrefs); ++j) {
451 if (IsCodec(voe_codec, kCodecPrefs[j].name) && 330 if (IsCodec(voe_codec, kCodecPrefs[j].name) &&
452 kCodecPrefs[j].clockrate == voe_codec.plfreq && 331 kCodecPrefs[j].clockrate == voe_codec.plfreq &&
453 kCodecPrefs[j].channels == voe_codec.channels) { 332 kCodecPrefs[j].channels == voe_codec.channels) {
(...skipping 22 matching lines...) Expand all
476 } 355 }
477 if (kPreferredMaxPTime != kOpusDefaultMaxPTime) { 356 if (kPreferredMaxPTime != kOpusDefaultMaxPTime) {
478 codec.params[kCodecParamMaxPTime] = 357 codec.params[kCodecParamMaxPTime] =
479 rtc::ToString(kPreferredMaxPTime); 358 rtc::ToString(kPreferredMaxPTime);
480 } 359 }
481 codec.SetParam(kCodecParamUseInbandFec, 1); 360 codec.SetParam(kCodecParamUseInbandFec, 1);
482 361
483 // TODO(hellner): Add ptime, sprop-stereo, and stereo 362 // TODO(hellner): Add ptime, sprop-stereo, and stereo
484 // when they can be set to values other than the default. 363 // when they can be set to values other than the default.
485 } 364 }
486 codecs_.push_back(codec); 365 result.push_back(codec);
487 } else { 366 } else {
488 LOG(LS_WARNING) << "Unexpected codec: " << ToString(voe_codec); 367 LOG(LS_WARNING) << "Unexpected codec: " << ToString(voe_codec);
489 } 368 }
490 } 369 }
370 // Make sure they are in local preference order.
371 std::sort(result.begin(), result.end(), &AudioCodec::Preferable);
372 return result;
491 } 373 }
492 // Make sure they are in local preference order. 374
493 std::sort(codecs_.begin(), codecs_.end(), &AudioCodec::Preferable); 375 static bool ToCodecInst(const AudioCodec& in,
376 webrtc::CodecInst* out) {
377 for (webrtc::CodecInst voe_codec : webrtc::acm2::RentACodec::Database()) {
378 // Change the sample rate of G722 to 8000 to match SDP.
379 MaybeFixupG722(&voe_codec, 8000);
380 AudioCodec codec(voe_codec.pltype, voe_codec.plname, voe_codec.plfreq,
381 voe_codec.rate, voe_codec.channels, 0);
382 bool multi_rate = IsCodecMultiRate(voe_codec);
383 // Allow arbitrary rates for ISAC to be specified.
384 if (multi_rate) {
385 // Set codec.bitrate to 0 so the check for codec.Matches() passes.
386 codec.bitrate = 0;
387 }
388 if (codec.Matches(in)) {
389 if (out) {
390 // Fixup the payload type.
391 voe_codec.pltype = in.id;
392
393 // Set bitrate if specified.
394 if (multi_rate && in.bitrate != 0) {
395 voe_codec.rate = in.bitrate;
396 }
397
398 // Reset G722 sample rate to 16000 to match WebRTC.
399 MaybeFixupG722(&voe_codec, 16000);
400
401 // Apply codec-specific settings.
402 if (IsCodec(codec, kIsacCodecName)) {
403 // If ISAC and an explicit bitrate is not specified,
404 // enable auto bitrate adjustment.
405 voe_codec.rate = (in.bitrate > 0) ? in.bitrate : -1;
406 }
407 *out = voe_codec;
408 }
409 return true;
410 }
411 }
412 return false;
413 }
414
415 static bool IsCodecMultiRate(const webrtc::CodecInst& codec) {
416 for (size_t i = 0; i < arraysize(kCodecPrefs); ++i) {
417 if (IsCodec(codec, kCodecPrefs[i].name) &&
418 kCodecPrefs[i].clockrate == codec.plfreq) {
419 return kCodecPrefs[i].is_multi_rate;
420 }
421 }
422 return false;
423 }
424
425 // If the AudioCodec param kCodecParamPTime is set, then we will set it to
426 // codec pacsize if it's valid, or we will pick the next smallest value we
427 // support.
428 // TODO(Brave): Query supported packet sizes from ACM when the API is ready.
429 static bool SetPTimeAsPacketSize(webrtc::CodecInst* codec, int ptime_ms) {
430 for (const CodecPref& codec_pref : kCodecPrefs) {
431 if ((IsCodec(*codec, codec_pref.name) &&
432 codec_pref.clockrate == codec->plfreq) ||
433 IsCodec(*codec, kG722CodecName)) {
434 int packet_size_ms = SelectPacketSize(codec_pref, ptime_ms);
435 if (packet_size_ms) {
436 // Convert unit from milli-seconds to samples.
437 codec->pacsize = (codec->plfreq / 1000) * packet_size_ms;
438 return true;
439 }
440 }
441 }
442 return false;
443 }
444
445 private:
446 static const int kMaxNumPacketSize = 6;
447 struct CodecPref {
448 const char* name;
449 int clockrate;
450 int channels;
451 int payload_type;
452 bool is_multi_rate;
453 int packet_sizes_ms[kMaxNumPacketSize];
454 };
455 // Note: keep the supported packet sizes in ascending order.
456 static const CodecPref kCodecPrefs[12];
457
458 static int SelectPacketSize(const CodecPref& codec_pref, int ptime_ms) {
459 int selected_packet_size_ms = codec_pref.packet_sizes_ms[0];
460 for (int packet_size_ms : codec_pref.packet_sizes_ms) {
461 if (packet_size_ms && packet_size_ms <= ptime_ms) {
462 selected_packet_size_ms = packet_size_ms;
463 }
464 }
465 return selected_packet_size_ms;
466 }
467
468 // Changes RTP timestamp rate of G722. This is due to the "bug" in the RFC
469 // which says that G722 should be advertised as 8 kHz although it is a 16 kHz
470 // codec.
471 static void MaybeFixupG722(webrtc::CodecInst* voe_codec, int new_plfreq) {
472 if (IsCodec(*voe_codec, kG722CodecName)) {
473 // If the ASSERT triggers, the codec definition in WebRTC VoiceEngine
474 // has changed, and this special case is no longer needed.
475 RTC_DCHECK(voe_codec->plfreq != new_plfreq);
476 voe_codec->plfreq = new_plfreq;
477 }
478 }
479 };
480
481 const WebRtcVoiceCodecs::CodecPref WebRtcVoiceCodecs::kCodecPrefs[12] = {
482 { kOpusCodecName, 48000, 2, 111, true, { 10, 20, 40, 60 } },
483 { kIsacCodecName, 16000, 1, 103, true, { 30, 60 } },
484 { kIsacCodecName, 32000, 1, 104, true, { 30 } },
485 // G722 should be advertised as 8000 Hz because of the RFC "bug".
486 { kG722CodecName, 8000, 1, 9, false, { 10, 20, 30, 40, 50, 60 } },
487 { kIlbcCodecName, 8000, 1, 102, false, { 20, 30, 40, 60 } },
488 { kPcmuCodecName, 8000, 1, 0, false, { 10, 20, 30, 40, 50, 60 } },
489 { kPcmaCodecName, 8000, 1, 8, false, { 10, 20, 30, 40, 50, 60 } },
490 { kCnCodecName, 32000, 1, 106, false, { } },
491 { kCnCodecName, 16000, 1, 105, false, { } },
492 { kCnCodecName, 8000, 1, 13, false, { } },
493 { kRedCodecName, 8000, 1, 127, false, { } },
494 { kDtmfCodecName, 8000, 1, 126, false, { } },
495 };
496 } // namespace {
497
498 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in,
499 webrtc::CodecInst* out) {
500 return WebRtcVoiceCodecs::ToCodecInst(in, out);
494 } 501 }
495 502
496 bool WebRtcVoiceEngine::GetVoeCodec(int index, webrtc::CodecInst* codec) { 503 WebRtcVoiceEngine::WebRtcVoiceEngine()
504 : voe_wrapper_(new VoEWrapper()),
505 audio_state_(webrtc::AudioState::Create(MakeAudioStateConfig(voe()))) {
506 Construct();
507 }
508
509 WebRtcVoiceEngine::WebRtcVoiceEngine(VoEWrapper* voe_wrapper)
510 : voe_wrapper_(voe_wrapper) {
511 Construct();
512 }
513
514 void WebRtcVoiceEngine::Construct() {
497 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 515 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
498 if (voe_wrapper_->codec()->GetCodec(index, *codec) == -1) { 516 LOG(LS_VERBOSE) << "WebRtcVoiceEngine::WebRtcVoiceEngine";
499 return false; 517
518 signal_thread_checker_.DetachFromThread();
519 std::memset(&default_agc_config_, 0, sizeof(default_agc_config_));
520
521 webrtc::Trace::set_level_filter(kDefaultTraceFilter);
522 webrtc::Trace::SetTraceCallback(this);
523
524 // Load our audio codec list.
525 codecs_ = WebRtcVoiceCodecs::SupportedCodecs();
526
527 // Load our RTP Header extensions.
528 rtp_header_extensions_.push_back(
529 RtpHeaderExtension(kRtpAudioLevelHeaderExtension,
530 kRtpAudioLevelHeaderExtensionDefaultId));
531 rtp_header_extensions_.push_back(
532 RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension,
533 kRtpAbsoluteSenderTimeHeaderExtensionDefaultId));
534 if (webrtc::field_trial::FindFullName("WebRTC-SendSideBwe") == "Enabled") {
535 rtp_header_extensions_.push_back(RtpHeaderExtension(
536 kRtpTransportSequenceNumberHeaderExtension,
537 kRtpTransportSequenceNumberHeaderExtensionDefaultId));
500 } 538 }
501 // Change the sample rate of G722 to 8000 to match SDP. 539 options_ = GetDefaultEngineOptions();
502 MaybeFixupG722(codec, 8000);
503 return true;
504 } 540 }
505 541
506 WebRtcVoiceEngine::~WebRtcVoiceEngine() { 542 WebRtcVoiceEngine::~WebRtcVoiceEngine() {
507 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 543 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
508 LOG(LS_VERBOSE) << "WebRtcVoiceEngine::~WebRtcVoiceEngine"; 544 LOG(LS_VERBOSE) << "WebRtcVoiceEngine::~WebRtcVoiceEngine";
509 if (adm_) { 545 if (adm_) {
510 voe_wrapper_.reset(); 546 voe_wrapper_.reset();
511 adm_->Release(); 547 adm_->Release();
512 adm_ = NULL; 548 adm_ = NULL;
513 } 549 }
(...skipping 18 matching lines...) Expand all
532 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 568 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
533 // Temporarily turn logging level up for the Init call 569 // Temporarily turn logging level up for the Init call
534 webrtc::Trace::set_level_filter(kElevatedTraceFilter); 570 webrtc::Trace::set_level_filter(kElevatedTraceFilter);
535 if (voe_wrapper_->base()->Init(adm_) == -1) { 571 if (voe_wrapper_->base()->Init(adm_) == -1) {
536 LOG_RTCERR0_EX(Init, voe_wrapper_->error()); 572 LOG_RTCERR0_EX(Init, voe_wrapper_->error());
537 return false; 573 return false;
538 } 574 }
539 webrtc::Trace::set_level_filter(kDefaultTraceFilter); 575 webrtc::Trace::set_level_filter(kDefaultTraceFilter);
540 576
541 // Log the VoiceEngine version info 577 // Log the VoiceEngine version info
542 char buffer[1024] = ""; 578 {
543 voe_wrapper_->base()->GetVersion(buffer); 579 char buffer[1024] = "";
544 LOG(LS_INFO) << "WebRtc VoiceEngine Version:"; 580 voe_wrapper_->base()->GetVersion(buffer);
545 LogMultiline(rtc::LS_INFO, buffer); 581 LOG(LS_INFO) << "WebRtc VoiceEngine Version:";
582 const char* delim = "\r\n";
583 for (char* tok = strtok(buffer, delim); tok; tok = strtok(NULL, delim)) {
584 LOG(LS_INFO) << tok;
585 }
586 }
546 587
547 // Save the default AGC configuration settings. This must happen before 588 // Save the default AGC configuration settings. This must happen before
548 // calling SetOptions or the default will be overwritten. 589 // calling SetOptions or the default will be overwritten.
549 if (voe_wrapper_->processing()->GetAgcConfig(default_agc_config_) == -1) { 590 if (voe_wrapper_->processing()->GetAgcConfig(default_agc_config_) == -1) {
550 LOG_RTCERR0(GetAgcConfig); 591 LOG_RTCERR0(GetAgcConfig);
551 return false; 592 return false;
552 } 593 }
553 594
554 // Set defaults for options, so that ApplyOptions applies them explicitly 595 // Set defaults for options, so that ApplyOptions applies them explicitly
555 // when we clear option (channel) overrides. External clients can still 596 // when we clear option (channel) overrides. External clients can still
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after
1049 unsigned int ulevel; 1090 unsigned int ulevel;
1050 return (voe_wrapper_->volume()->GetSpeechInputLevel(ulevel) != -1) ? 1091 return (voe_wrapper_->volume()->GetSpeechInputLevel(ulevel) != -1) ?
1051 static_cast<int>(ulevel) : -1; 1092 static_cast<int>(ulevel) : -1;
1052 } 1093 }
1053 1094
1054 const std::vector<AudioCodec>& WebRtcVoiceEngine::codecs() { 1095 const std::vector<AudioCodec>& WebRtcVoiceEngine::codecs() {
1055 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread()); 1096 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread());
1056 return codecs_; 1097 return codecs_;
1057 } 1098 }
1058 1099
1059 bool WebRtcVoiceEngine::FindCodec(const AudioCodec& in) {
1060 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1061 return FindWebRtcCodec(in, NULL);
1062 }
1063
1064 // Get the VoiceEngine codec that matches |in|, with the supplied settings.
1065 bool WebRtcVoiceEngine::FindWebRtcCodec(const AudioCodec& in,
1066 webrtc::CodecInst* out) {
1067 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1068 int ncodecs = voe_wrapper_->codec()->NumOfCodecs();
1069 for (int i = 0; i < ncodecs; ++i) {
1070 webrtc::CodecInst voe_codec;
1071 if (GetVoeCodec(i, &voe_codec)) {
1072 AudioCodec codec(voe_codec.pltype, voe_codec.plname, voe_codec.plfreq,
1073 voe_codec.rate, voe_codec.channels, 0);
1074 bool multi_rate = IsCodecMultiRate(voe_codec);
1075 // Allow arbitrary rates for ISAC to be specified.
1076 if (multi_rate) {
1077 // Set codec.bitrate to 0 so the check for codec.Matches() passes.
1078 codec.bitrate = 0;
1079 }
1080 if (codec.Matches(in)) {
1081 if (out) {
1082 // Fixup the payload type.
1083 voe_codec.pltype = in.id;
1084
1085 // Set bitrate if specified.
1086 if (multi_rate && in.bitrate != 0) {
1087 voe_codec.rate = in.bitrate;
1088 }
1089
1090 // Reset G722 sample rate to 16000 to match WebRTC.
1091 MaybeFixupG722(&voe_codec, 16000);
1092
1093 // Apply codec-specific settings.
1094 if (IsCodec(codec, kIsacCodecName)) {
1095 // If ISAC and an explicit bitrate is not specified,
1096 // enable auto bitrate adjustment.
1097 voe_codec.rate = (in.bitrate > 0) ? in.bitrate : -1;
1098 }
1099 *out = voe_codec;
1100 }
1101 return true;
1102 }
1103 }
1104 }
1105 return false;
1106 }
1107
1108 const std::vector<RtpHeaderExtension>& 1100 const std::vector<RtpHeaderExtension>&
1109 WebRtcVoiceEngine::rtp_header_extensions() const { 1101 WebRtcVoiceEngine::rtp_header_extensions() const {
1110 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread()); 1102 RTC_DCHECK(signal_thread_checker_.CalledOnValidThread());
1111 return rtp_header_extensions_; 1103 return rtp_header_extensions_;
1112 } 1104 }
1113 1105
1114 int WebRtcVoiceEngine::GetLastEngineError() { 1106 int WebRtcVoiceEngine::GetLastEngineError() {
1115 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 1107 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1116 return voe_wrapper_->error(); 1108 return voe_wrapper_->error();
1117 } 1109 }
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after
1585 // never removed. 1577 // never removed.
1586 return true; 1578 return true;
1587 } 1579 }
1588 1580
1589 if (playout_) { 1581 if (playout_) {
1590 // Receive codecs can not be changed while playing. So we temporarily 1582 // Receive codecs can not be changed while playing. So we temporarily
1591 // pause playout. 1583 // pause playout.
1592 PausePlayout(); 1584 PausePlayout();
1593 } 1585 }
1594 1586
1595 bool result = SetRecvCodecsInternal(new_codecs); 1587 bool result = true;
1588 for (const AudioCodec& codec : new_codecs) {
1589 webrtc::CodecInst voe_codec;
1590 if (WebRtcVoiceEngine::ToCodecInst(codec, &voe_codec)) {
1591 LOG(LS_INFO) << ToString(codec);
1592 voe_codec.pltype = codec.id;
1593 for (const auto& ch : recv_streams_) {
1594 if (engine()->voe()->codec()->SetRecPayloadType(
1595 ch.second->channel(), voe_codec) == -1) {
1596 LOG_RTCERR2(SetRecPayloadType, ch.second->channel(),
1597 ToString(voe_codec));
1598 result = false;
1599 }
1600 }
1601 } else {
1602 LOG(LS_WARNING) << "Unknown codec " << ToString(codec);
1603 result = false;
1604 break;
1605 }
1606 }
1596 if (result) { 1607 if (result) {
1597 recv_codecs_ = codecs; 1608 recv_codecs_ = codecs;
1598 } 1609 }
1599 1610
1600 if (desired_playout_ && !playout_) { 1611 if (desired_playout_ && !playout_) {
1601 ResumePlayout(); 1612 ResumePlayout();
1602 } 1613 }
1603 return result; 1614 return result;
1604 } 1615 }
1605 1616
(...skipping 14 matching lines...) Expand all
1620 bool nack_enabled = nack_enabled_; 1631 bool nack_enabled = nack_enabled_;
1621 bool enable_codec_fec = false; 1632 bool enable_codec_fec = false;
1622 bool enable_opus_dtx = false; 1633 bool enable_opus_dtx = false;
1623 int opus_max_playback_rate = 0; 1634 int opus_max_playback_rate = 0;
1624 1635
1625 // Set send codec (the first non-telephone-event/CN codec) 1636 // Set send codec (the first non-telephone-event/CN codec)
1626 for (const AudioCodec& codec : codecs) { 1637 for (const AudioCodec& codec : codecs) {
1627 // Ignore codecs we don't know about. The negotiation step should prevent 1638 // Ignore codecs we don't know about. The negotiation step should prevent
1628 // this, but double-check to be sure. 1639 // this, but double-check to be sure.
1629 webrtc::CodecInst voe_codec; 1640 webrtc::CodecInst voe_codec;
1630 if (!engine()->FindWebRtcCodec(codec, &voe_codec)) { 1641 if (!WebRtcVoiceEngine::ToCodecInst(codec, &voe_codec)) {
1631 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); 1642 LOG(LS_WARNING) << "Unknown codec " << ToString(codec);
1632 continue; 1643 continue;
1633 } 1644 }
1634 1645
1635 if (IsCodec(codec, kDtmfCodecName) || IsCodec(codec, kCnCodecName)) { 1646 if (IsCodec(codec, kDtmfCodecName) || IsCodec(codec, kCnCodecName)) {
1636 // Skip telephone-event/CN codec, which will be handled later. 1647 // Skip telephone-event/CN codec, which will be handled later.
1637 continue; 1648 continue;
1638 } 1649 }
1639 1650
1640 // We'll use the first codec in the list to actually send audio data. 1651 // We'll use the first codec in the list to actually send audio data.
(...skipping 20 matching lines...) Expand all
1661 // For Opus as the send codec, we are to determine inband FEC, maximum 1672 // For Opus as the send codec, we are to determine inband FEC, maximum
1662 // playback rate, and opus internal dtx. 1673 // playback rate, and opus internal dtx.
1663 if (IsCodec(codec, kOpusCodecName)) { 1674 if (IsCodec(codec, kOpusCodecName)) {
1664 GetOpusConfig(codec, &send_codec, &enable_codec_fec, 1675 GetOpusConfig(codec, &send_codec, &enable_codec_fec,
1665 &opus_max_playback_rate, &enable_opus_dtx); 1676 &opus_max_playback_rate, &enable_opus_dtx);
1666 } 1677 }
1667 1678
1668 // Set packet size if the AudioCodec param kCodecParamPTime is set. 1679 // Set packet size if the AudioCodec param kCodecParamPTime is set.
1669 int ptime_ms = 0; 1680 int ptime_ms = 0;
1670 if (codec.GetParam(kCodecParamPTime, &ptime_ms)) { 1681 if (codec.GetParam(kCodecParamPTime, &ptime_ms)) {
1671 if (!SetPTimeAsPacketSize(&send_codec, ptime_ms)) { 1682 if (!WebRtcVoiceCodecs::SetPTimeAsPacketSize(&send_codec, ptime_ms)) {
1672 LOG(LS_WARNING) << "Failed to set packet size for codec " 1683 LOG(LS_WARNING) << "Failed to set packet size for codec "
1673 << send_codec.plname; 1684 << send_codec.plname;
1674 return false; 1685 return false;
1675 } 1686 }
1676 } 1687 }
1677 } 1688 }
1678 found_send_codec = true; 1689 found_send_codec = true;
1679 break; 1690 break;
1680 } 1691 }
1681 1692
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1739 1750
1740 if (send_bitrate_setting_) { 1751 if (send_bitrate_setting_) {
1741 SetSendBitrateInternal(send_bitrate_bps_); 1752 SetSendBitrateInternal(send_bitrate_bps_);
1742 } 1753 }
1743 1754
1744 // Loop through the codecs list again to config the telephone-event/CN codec. 1755 // Loop through the codecs list again to config the telephone-event/CN codec.
1745 for (const AudioCodec& codec : codecs) { 1756 for (const AudioCodec& codec : codecs) {
1746 // Ignore codecs we don't know about. The negotiation step should prevent 1757 // Ignore codecs we don't know about. The negotiation step should prevent
1747 // this, but double-check to be sure. 1758 // this, but double-check to be sure.
1748 webrtc::CodecInst voe_codec; 1759 webrtc::CodecInst voe_codec;
1749 if (!engine()->FindWebRtcCodec(codec, &voe_codec)) { 1760 if (!WebRtcVoiceEngine::ToCodecInst(codec, &voe_codec)) {
1750 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); 1761 LOG(LS_WARNING) << "Unknown codec " << ToString(codec);
1751 continue; 1762 continue;
1752 } 1763 }
1753 1764
1754 // Find the DTMF telephone event "codec" and tell VoiceEngine channels 1765 // Find the DTMF telephone event "codec" and tell VoiceEngine channels
1755 // about it. 1766 // about it.
1756 if (IsCodec(codec, kDtmfCodecName)) { 1767 if (IsCodec(codec, kDtmfCodecName)) {
1757 if (engine()->voe()->dtmf()->SetSendTelephoneEventPayloadType( 1768 if (engine()->voe()->dtmf()->SetSendTelephoneEventPayloadType(
1758 channel, codec.id) == -1) { 1769 channel, codec.id) == -1) {
1759 LOG_RTCERR2(SetSendTelephoneEventPayloadType, channel, codec.id); 1770 LOG_RTCERR2(SetSendTelephoneEventPayloadType, channel, codec.id);
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
2109 return false; 2120 return false;
2110 } 2121 }
2111 2122
2112 // Create a new channel for receiving audio data. 2123 // Create a new channel for receiving audio data.
2113 const int channel = CreateVoEChannel(); 2124 const int channel = CreateVoEChannel();
2114 if (channel == -1) { 2125 if (channel == -1) {
2115 return false; 2126 return false;
2116 } 2127 }
2117 2128
2118 // Turn off all supported codecs. 2129 // Turn off all supported codecs.
2119 const int ncodecs = engine()->voe()->codec()->NumOfCodecs(); 2130 // TODO(solenberg): Remove once "no codecs" is the default state of a stream.
2120 for (int i = 0; i < ncodecs; ++i) { 2131 for (webrtc::CodecInst voe_codec : webrtc::acm2::RentACodec::Database()) {
2121 webrtc::CodecInst voe_codec; 2132 voe_codec.pltype = -1;
2122 if (engine()->voe()->codec()->GetCodec(i, voe_codec) != -1) { 2133 if (engine()->voe()->codec()->SetRecPayloadType(channel, voe_codec) == -1) {
2123 voe_codec.pltype = -1; 2134 LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec));
2124 if (engine()->voe()->codec()->SetRecPayloadType( 2135 DeleteVoEChannel(channel);
2125 channel, voe_codec) == -1) { 2136 return false;
2126 LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec));
2127 DeleteVoEChannel(channel);
2128 return false;
2129 }
2130 } 2137 }
2131 } 2138 }
2132 2139
2133 // Only enable those configured for this channel. 2140 // Only enable those configured for this channel.
2134 for (const auto& codec : recv_codecs_) { 2141 for (const auto& codec : recv_codecs_) {
2135 webrtc::CodecInst voe_codec; 2142 webrtc::CodecInst voe_codec;
2136 if (engine()->FindWebRtcCodec(codec, &voe_codec)) { 2143 if (WebRtcVoiceEngine::ToCodecInst(codec, &voe_codec)) {
2137 voe_codec.pltype = codec.id; 2144 voe_codec.pltype = codec.id;
2138 if (engine()->voe()->codec()->SetRecPayloadType( 2145 if (engine()->voe()->codec()->SetRecPayloadType(
2139 channel, voe_codec) == -1) { 2146 channel, voe_codec) == -1) {
2140 LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec)); 2147 LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec));
2141 DeleteVoEChannel(channel); 2148 DeleteVoEChannel(channel);
2142 return false; 2149 return false;
2143 } 2150 }
2144 } 2151 }
2145 } 2152 }
2146 2153
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
2479 return true; 2486 return true;
2480 } 2487 }
2481 2488
2482 // Bitrate is auto by default. 2489 // Bitrate is auto by default.
2483 // TODO(bemasc): Fix this so that if SetMaxSendBandwidth(50) is followed by 2490 // TODO(bemasc): Fix this so that if SetMaxSendBandwidth(50) is followed by
2484 // SetMaxSendBandwith(0), the second call removes the previous limit. 2491 // SetMaxSendBandwith(0), the second call removes the previous limit.
2485 if (bps <= 0) 2492 if (bps <= 0)
2486 return true; 2493 return true;
2487 2494
2488 webrtc::CodecInst codec = *send_codec_; 2495 webrtc::CodecInst codec = *send_codec_;
2489 bool is_multi_rate = IsCodecMultiRate(codec); 2496 bool is_multi_rate = WebRtcVoiceCodecs::IsCodecMultiRate(codec);
2490 2497
2491 if (is_multi_rate) { 2498 if (is_multi_rate) {
2492 // If codec is multi-rate then just set the bitrate. 2499 // If codec is multi-rate then just set the bitrate.
2493 codec.rate = bps; 2500 codec.rate = bps;
2494 for (const auto& ch : send_streams_) { 2501 for (const auto& ch : send_streams_) {
2495 if (!SetSendCodec(ch.second->channel(), codec)) { 2502 if (!SetSendCodec(ch.second->channel(), codec)) {
2496 LOG(LS_INFO) << "Failed to set codec " << codec.plname 2503 LOG(LS_INFO) << "Failed to set codec " << codec.plname
2497 << " to bitrate " << bps << " bps."; 2504 << " to bitrate " << bps << " bps.";
2498 return false; 2505 return false;
2499 } 2506 }
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
2628 if (all_codecs.size() > 1) { 2635 if (all_codecs.size() > 1) {
2629 red_pt = all_codecs[1].id; 2636 red_pt = all_codecs[1].id;
2630 } 2637 }
2631 } 2638 }
2632 2639
2633 // Try to find red_pt in |codecs|. 2640 // Try to find red_pt in |codecs|.
2634 for (const AudioCodec& codec : all_codecs) { 2641 for (const AudioCodec& codec : all_codecs) {
2635 if (codec.id == red_pt) { 2642 if (codec.id == red_pt) {
2636 // If we find the right codec, that will be the codec we pass to 2643 // If we find the right codec, that will be the codec we pass to
2637 // SetSendCodec, with the desired payload type. 2644 // SetSendCodec, with the desired payload type.
2638 if (engine()->FindWebRtcCodec(codec, send_codec)) { 2645 if (WebRtcVoiceEngine::ToCodecInst(codec, send_codec)) {
2639 return true; 2646 return true;
2640 } else { 2647 } else {
2641 break; 2648 break;
2642 } 2649 }
2643 } 2650 }
2644 } 2651 }
2645 LOG(LS_WARNING) << "RED params " << red_params << " are invalid."; 2652 LOG(LS_WARNING) << "RED params " << red_params << " are invalid.";
2646 return false; 2653 return false;
2647 } 2654 }
2648 2655
2649 bool WebRtcVoiceMediaChannel::SetPlayout(int channel, bool playout) { 2656 bool WebRtcVoiceMediaChannel::SetPlayout(int channel, bool playout) {
2650 if (playout) { 2657 if (playout) {
2651 LOG(LS_INFO) << "Starting playout for channel #" << channel; 2658 LOG(LS_INFO) << "Starting playout for channel #" << channel;
2652 if (engine()->voe()->base()->StartPlayout(channel) == -1) { 2659 if (engine()->voe()->base()->StartPlayout(channel) == -1) {
2653 LOG_RTCERR1(StartPlayout, channel); 2660 LOG_RTCERR1(StartPlayout, channel);
2654 return false; 2661 return false;
2655 } 2662 }
2656 } else { 2663 } else {
2657 LOG(LS_INFO) << "Stopping playout for channel #" << channel; 2664 LOG(LS_INFO) << "Stopping playout for channel #" << channel;
2658 engine()->voe()->base()->StopPlayout(channel); 2665 engine()->voe()->base()->StopPlayout(channel);
2659 } 2666 }
2660 return true; 2667 return true;
2661 } 2668 }
2662
2663 bool WebRtcVoiceMediaChannel::SetRecvCodecsInternal(
2664 const std::vector<AudioCodec>& new_codecs) {
2665 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
2666 for (const AudioCodec& codec : new_codecs) {
2667 webrtc::CodecInst voe_codec;
2668 if (engine()->FindWebRtcCodec(codec, &voe_codec)) {
2669 LOG(LS_INFO) << ToString(codec);
2670 voe_codec.pltype = codec.id;
2671 for (const auto& ch : recv_streams_) {
2672 if (engine()->voe()->codec()->SetRecPayloadType(
2673 ch.second->channel(), voe_codec) == -1) {
2674 LOG_RTCERR2(SetRecPayloadType, ch.second->channel(),
2675 ToString(voe_codec));
2676 return false;
2677 }
2678 }
2679 } else {
2680 LOG(LS_WARNING) << "Unknown codec " << ToString(codec);
2681 return false;
2682 }
2683 }
2684 return true;
2685 }
2686 } // namespace cricket 2669 } // namespace cricket
2687 2670
2688 #endif // HAVE_WEBRTC_VOICE 2671 #endif // HAVE_WEBRTC_VOICE
OLDNEW
« no previous file with comments | « talk/media/webrtc/webrtcvoiceengine.h ('k') | talk/media/webrtc/webrtcvoiceengine_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698