2013-07-10 00:45:36 +00:00
/*
2016-02-07 20:46:45 -08:00
* Copyright ( c ) 2004 The WebRTC project authors . All Rights Reserved .
2013-07-10 00:45:36 +00:00
*
2016-02-07 20:46:45 -08:00
* 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 .
2013-07-10 00:45:36 +00:00
*/
# ifdef HAVE_WEBRTC_VOICE
2016-02-12 06:39:40 +01:00
# include "webrtc/media/engine/webrtcvoiceengine.h"
2013-07-10 00:45:36 +00:00
# include <algorithm>
# include <cstdio>
2016-08-17 02:45:41 -07:00
# include <functional>
2013-07-10 00:45:36 +00:00
# include <string>
# include <vector>
2016-08-31 07:33:05 -07:00
# include "webrtc/api/call/audio_sink.h"
2016-03-08 12:37:39 -08:00
# include "webrtc/media/base/audiosource.h"
2016-03-02 05:42:30 -08:00
# include "webrtc/media/base/mediaconstants.h"
Move talk/media to webrtc/media
I removed the 'libjingle' target in talk/libjingle.gyp and replaced
all users of it with base/base.gyp:rtc_base. It seems the jsoncpp
and expat dependencies were not used by it's previous references.
The files in talk/media/testdata were uploaded to Google Storage and
added .sha1 files in resources/media instead of simply moving them.
The previously disabled warnings that were inherited from
talk/build/common.gypi are now replaced by target-specific disabling
of only the failing warnings. Additional disabling was needed since the stricter
compilation warnings that applies to code in webrtc/.
License headers will be updated in a follow-up CL in order to not
break Git history.
Other modifications:
* Updated the header guards.
* Sorted the includes using chromium/src/tools/sort-headers.py
except for these files:
talk/app/webrtc/peerconnectionendtoend_unittest.cc
talk/app/webrtc/java/jni/androidmediadecoder_jni.cc
talk/app/webrtc/java/jni/androidmediaencoder_jni.cc
webrtc/media/devices/win32devicemanager.cc.
* Unused GYP reference to libjingle_tests_additional_deps was removed.
* Removed duplicated GYP entries of
webrtc/base/testutils.cc
webrtc/base/testutils.h
The HAVE_WEBRTC_VIDEO and HAVE_WEBRTC_VOICE defines were used by only talk/media,
so they were moved to the media.gyp.
I also checked that none of
EXPAT_RELATIVE_PATH,
FEATURE_ENABLE_VOICEMAIL,
GTEST_RELATIVE_PATH,
JSONCPP_RELATIVE_PATH,
LOGGING=1,
SRTP_RELATIVE_PATH,
FEATURE_ENABLE_SSL,
FEATURE_ENABLE_VOICEMAIL,
FEATURE_ENABLE_PSTN,
HAVE_SCTP,
HAVE_SRTP,
are used by the talk/media code.
For Chromium, the following changes will need to be applied to the roll CL that updates the
DEPS for WebRTC and libjingle: https://codereview.chromium.org/1604303002/
BUG=webrtc:5420
NOPRESUBMIT=True
TBR=tommi@webrtc.org
Review URL: https://codereview.webrtc.org/1587193006
Cr-Commit-Position: refs/heads/master@{#11495}
2016-02-04 23:52:28 -08:00
# include "webrtc/media/base/streamparams.h"
2017-03-15 06:14:12 -07:00
# include "webrtc/media/engine/adm_helpers.h"
2017-02-21 00:54:31 -08:00
# include "webrtc/media/engine/apm_helpers.h"
2016-08-17 02:45:41 -07:00
# include "webrtc/media/engine/payload_type_mapper.h"
2016-02-12 06:39:40 +01:00
# include "webrtc/media/engine/webrtcmediaengine.h"
# include "webrtc/media/engine/webrtcvoe.h"
2016-11-17 06:48:48 -08:00
# include "webrtc/modules/audio_mixer/audio_mixer_impl.h"
Reland of Activate 'offload debug dump recordings from audio thread to TaskQueue'. (patchset #1 id:1 of https://codereview.webrtc.org/2910633002/ )
Reason for revert:
Revert of revert of revert of revert of 'Activating..'. Or "reland of reland of 'Activate..'".
*Now* the internal projects are fixed and the fix is verified.
Original issue's description:
> Revert of Activate 'offload debug dump recordings from audio thread to TaskQueue'. (patchset #1 id:1 of https://codereview.webrtc.org/2903153005/ )
>
> Reason for revert:
> Reverting again: internal project issues were apparently not completely fixed.
>
> Original issue's description:
> > Reland of Activate 'offload debug dump recordings from audio thread to TaskQueue'. (patchset #1 id:1 of https://codereview.webrtc.org/2904893002/ )
> >
> > Reason for revert:
> > Revert the revert now that internal projects are updated.
> >
> > Original issue's description:
> > > Revert of Activate 'offload debug dump recordings from audio thread to TaskQueue'. (patchset #4 id:160001 of https://codereview.webrtc.org/2896813002/ )
> > >
> > > Reason for revert:
> > > Breaks internal project.
> > >
> > > Original issue's description:
> > > > Activate 'offload debug dump recordings from audio thread to TaskQueue'.
> > > >
> > > > A low priority task queue is added to WebRTCVoiceEngine. The
> > > > start/stop debug calls make file logging happen on the task queue.
> > > >
> > > > In a dependent CL (https://codereview.webrtc.org/2888303003), the task queue is moved to PeerConnectionFactory,
> > > > so that it can be shared for low priority tasks between different
> > > > subcomponents. It will require some changes to MediaEngine,
> > > > CompositeMediaEngine, WebRTCVoiceEngine, and changes in internal
> > > > projects.
> > > >
> > > > A task queue must be created and destroyed from the same thread. With
> > > > this CL that will be the worker thread, which creates and destroys
> > > > WebRTCVoiceEngine. With the dependent CL, it will probably change to
> > > > the signaling thread.
> > > >
> > > > NOTRY=True # tests just passed
> > > >
> > > > BUG=webrtc:7404
> > > >
> > > > Review-Url: https://codereview.webrtc.org/2896813002
> > > > Cr-Commit-Position: refs/heads/master@{#18252}
> > > > Committed: https://chromium.googlesource.com/external/webrtc/+/c61bf947b4ac31f3500858ffcae6fee39d799930
> > >
> > > TBR=solenberg@webrtc.org,tommi@webrtc.org,perkj@webrtc.org,danilchap@webrtc.org,tommi@chromium.org
> > > # Skipping CQ checks because original CL landed less than 1 days ago.
> > > NOPRESUBMIT=true
> > > NOTREECHECKS=true
> > > NOTRY=true
> > > BUG=webrtc:7404
> > >
> > > Review-Url: https://codereview.webrtc.org/2904893002
> > > Cr-Commit-Position: refs/heads/master@{#18255}
> > > Committed: https://chromium.googlesource.com/external/webrtc/+/be68b72cfad0686dcd892bba1368b199a7ee16ca
> >
> > TBR=solenberg@webrtc.org,tommi@webrtc.org,perkj@webrtc.org,danilchap@webrtc.org,tommi@chromium.org
> > # Not skipping CQ checks because original CL landed more than 1 days ago.
> > BUG=webrtc:7404
> >
> > Review-Url: https://codereview.webrtc.org/2903153005
> > Cr-Commit-Position: refs/heads/master@{#18270}
> > Committed: https://chromium.googlesource.com/external/webrtc/+/d2303a2338106feab684860f1c133877b46bdd4f
>
> TBR=solenberg@webrtc.org,tommi@webrtc.org,perkj@webrtc.org,danilchap@webrtc.org,tommi@chromium.org
> # Skipping CQ checks because original CL landed less than 1 days ago.
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:7404
>
> Review-Url: https://codereview.webrtc.org/2910633002
> Cr-Commit-Position: refs/heads/master@{#18272}
> Committed: https://chromium.googlesource.com/external/webrtc/+/fe9ecb07ea8254d8a09605f25203a4d045b3ffee
TBR=solenberg@webrtc.org,tommi@webrtc.org,perkj@webrtc.org,danilchap@webrtc.org,tommi@chromium.org
# Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=webrtc:7404
Review-Url: https://codereview.webrtc.org/2904423002
Cr-Commit-Position: refs/heads/master@{#18300}
2017-05-29 02:56:27 -07:00
# include "webrtc/modules/audio_processing/aec_dump/aec_dump_factory.h"
2013-07-10 00:45:36 +00:00
# include "webrtc/modules/audio_processing/include/audio_processing.h"
2017-07-06 19:44:34 +02:00
# include "webrtc/rtc_base/arraysize.h"
# include "webrtc/rtc_base/base64.h"
# include "webrtc/rtc_base/byteorder.h"
# include "webrtc/rtc_base/constructormagic.h"
# include "webrtc/rtc_base/helpers.h"
# include "webrtc/rtc_base/logging.h"
# include "webrtc/rtc_base/race_checker.h"
# include "webrtc/rtc_base/stringencode.h"
# include "webrtc/rtc_base/stringutils.h"
# include "webrtc/rtc_base/trace_event.h"
2015-10-28 18:17:40 +01:00
# include "webrtc/system_wrappers/include/field_trial.h"
2017-03-01 11:29:29 -08:00
# include "webrtc/system_wrappers/include/metrics.h"
2015-11-20 16:08:07 -08:00
# include "webrtc/system_wrappers/include/trace.h"
2017-02-21 00:54:31 -08:00
# include "webrtc/voice_engine/transmit_mixer.h"
2013-07-10 00:45:36 +00:00
namespace cricket {
2015-10-07 01:40:33 -07:00
namespace {
2013-07-10 00:45:36 +00:00
2017-06-13 00:38:27 -07:00
constexpr size_t kMaxUnsignaledRecvStreams = 4 ;
2017-03-01 11:29:29 -08:00
2015-11-20 16:08:07 -08:00
const int kDefaultTraceFilter = webrtc : : kTraceNone | webrtc : : kTraceTerseInfo |
webrtc : : kTraceWarning | webrtc : : kTraceError |
webrtc : : kTraceCritical ;
const int kElevatedTraceFilter = kDefaultTraceFilter | webrtc : : kTraceStateInfo |
webrtc : : kTraceInfo ;
2016-06-14 10:02:41 -07:00
constexpr int kNackRtpHistoryMs = 5000 ;
2014-10-31 05:33:10 +00:00
2016-08-26 07:16:04 -07:00
// Check to verify that the define for the intelligibility enhancer is properly
// set.
# if !defined(WEBRTC_INTELLIGIBILITY_ENHANCER) || \
( WEBRTC_INTELLIGIBILITY_ENHANCER ! = 0 & & \
WEBRTC_INTELLIGIBILITY_ENHANCER ! = 1 )
# error "Set WEBRTC_INTELLIGIBILITY_ENHANCER to either 0 or 1"
# endif
2017-04-27 02:08:52 -07:00
// For SendSideBwe, Opus bitrate should be in the range between 6000 and 32000.
2016-11-07 09:29:22 -08:00
const int kOpusMinBitrateBps = 6000 ;
2017-04-27 02:08:52 -07:00
const int kOpusBitrateFbBps = 32000 ;
2016-04-27 14:17:10 -07:00
2013-10-31 15:40:38 +00:00
// Default audio dscp value.
// See http://tools.ietf.org/html/rfc2474 for details.
// See also http://tools.ietf.org/html/draft-jennings-rtcweb-qos-00
2015-10-07 01:40:33 -07:00
const rtc : : DiffServCodePoint kAudioDscpValue = rtc : : DSCP_EF ;
2013-07-26 19:17:59 +00:00
2015-12-04 15:22:19 +01:00
// Constants from voice_engine_defines.h.
const int kMinTelephoneEventCode = 0 ; // RFC4733 (Section 2.3.1)
const int kMaxTelephoneEventCode = 255 ;
2016-03-14 08:00:37 -07:00
const int kMinPayloadType = 0 ;
const int kMaxPayloadType = 127 ;
2016-01-15 09:20:04 -08:00
class ProxySink : public webrtc : : AudioSinkInterface {
public :
ProxySink ( AudioSinkInterface * sink ) : sink_ ( sink ) { RTC_DCHECK ( sink ) ; }
void OnData ( const Data & audio ) override { sink_ - > OnData ( audio ) ; }
private :
webrtc : : AudioSinkInterface * sink_ ;
} ;
2015-10-09 01:37:09 -07:00
bool ValidateStreamParams ( const StreamParams & sp ) {
if ( sp . ssrcs . empty ( ) ) {
LOG ( LS_ERROR ) < < " No SSRCs in stream parameters: " < < sp . ToString ( ) ;
return false ;
}
if ( sp . ssrcs . size ( ) > 1 ) {
LOG ( LS_ERROR ) < < " Multiple SSRCs in stream parameters: " < < sp . ToString ( ) ;
return false ;
}
return true ;
}
2013-07-10 00:45:36 +00:00
// Dumps an AudioCodec in RFC 2327-ish format.
2015-10-07 01:40:33 -07:00
std : : string ToString ( const AudioCodec & codec ) {
2013-07-10 00:45:36 +00:00
std : : stringstream ss ;
2017-04-27 02:08:52 -07:00
ss < < codec . name < < " / " < < codec . clockrate < < " / " < < codec . channels ;
if ( ! codec . params . empty ( ) ) {
ss < < " { " ;
for ( const auto & param : codec . params ) {
ss < < " " < < param . first < < " = " < < param . second ;
}
ss < < " } " ;
}
ss < < " ( " < < codec . id < < " ) " ;
2013-07-10 00:45:36 +00:00
return ss . str ( ) ;
}
2015-03-27 05:05:59 +01:00
2015-10-07 01:40:33 -07:00
bool IsCodec ( const AudioCodec & codec , const char * ref_name ) {
2015-03-27 05:05:59 +01:00
return ( _stricmp ( codec . name . c_str ( ) , ref_name ) = = 0 ) ;
}
2015-10-07 01:40:33 -07:00
bool FindCodec ( const std : : vector < AudioCodec > & codecs ,
2015-11-27 04:00:25 -08:00
const AudioCodec & codec ,
AudioCodec * found_codec ) {
2015-08-26 10:45:53 +02:00
for ( const AudioCodec & c : codecs ) {
if ( c . Matches ( codec ) ) {
2013-07-10 00:45:36 +00:00
if ( found_codec ! = NULL ) {
2015-08-26 10:45:53 +02:00
* found_codec = c ;
2013-07-10 00:45:36 +00:00
}
return true ;
}
}
return false ;
}
2013-10-16 18:12:02 +00:00
2015-10-09 01:37:09 -07:00
bool VerifyUniquePayloadTypes ( const std : : vector < AudioCodec > & codecs ) {
if ( codecs . empty ( ) ) {
return true ;
}
std : : vector < int > payload_types ;
for ( const AudioCodec & codec : codecs ) {
payload_types . push_back ( codec . id ) ;
}
std : : sort ( payload_types . begin ( ) , payload_types . end ( ) ) ;
auto it = std : : unique ( payload_types . begin ( ) , payload_types . end ( ) ) ;
return it = = payload_types . end ( ) ;
}
2016-10-31 04:08:32 -07:00
rtc : : Optional < std : : string > GetAudioNetworkAdaptorConfig (
const AudioOptions & options ) {
if ( options . audio_network_adaptor & & * options . audio_network_adaptor & &
options . audio_network_adaptor_config ) {
// Turn on audio network adaptor only when |options_.audio_network_adaptor|
// equals true and |options_.audio_network_adaptor_config| has a value.
return options . audio_network_adaptor_config ;
}
return rtc : : Optional < std : : string > ( ) ;
}
2016-12-13 14:06:26 -08:00
webrtc : : AudioState : : Config MakeAudioStateConfig (
VoEWrapper * voe_wrapper ,
2017-06-29 08:32:09 -07:00
rtc : : scoped_refptr < webrtc : : AudioMixer > audio_mixer ,
rtc : : scoped_refptr < webrtc : : AudioProcessing > audio_processing ) {
2015-11-06 15:34:49 -08:00
webrtc : : AudioState : : Config config ;
config . voice_engine = voe_wrapper - > engine ( ) ;
2016-12-13 14:06:26 -08:00
if ( audio_mixer ) {
config . audio_mixer = audio_mixer ;
} else {
config . audio_mixer = webrtc : : AudioMixerImpl : : Create ( ) ;
}
2017-06-29 08:32:09 -07:00
config . audio_processing = audio_processing ;
2015-11-06 15:34:49 -08:00
return config ;
}
2017-02-04 12:09:01 -08:00
// |max_send_bitrate_bps| is the bitrate from "b=" in SDP.
// |rtp_max_bitrate_bps| is the bitrate from RtpSender::SetParameters.
2016-10-20 03:27:12 -07:00
rtc : : Optional < int > ComputeSendBitrate ( int max_send_bitrate_bps ,
2017-02-04 12:09:01 -08:00
rtc : : Optional < int > rtp_max_bitrate_bps ,
2017-04-27 02:08:52 -07:00
const webrtc : : AudioCodecSpec & spec ) {
2017-02-04 12:09:01 -08:00
// If application-configured bitrate is set, take minimum of that and SDP
// bitrate.
2017-06-14 11:41:48 -07:00
const int bps =
rtp_max_bitrate_bps
? webrtc : : MinPositive ( max_send_bitrate_bps , * rtp_max_bitrate_bps )
: max_send_bitrate_bps ;
2016-10-20 03:27:12 -07:00
if ( bps < = 0 ) {
2017-04-27 02:08:52 -07:00
return rtc : : Optional < int > ( spec . info . default_bitrate_bps ) ;
2016-06-14 10:02:41 -07:00
}
2016-10-20 03:27:12 -07:00
2017-04-27 02:08:52 -07:00
if ( bps < spec . info . min_bitrate_bps ) {
2016-10-20 03:27:12 -07:00
// If codec is not multi-rate and |bps| is less than the fixed bitrate then
// fail. If codec is not multi-rate and |bps| exceeds or equal the fixed
// bitrate then ignore.
2017-04-27 02:08:52 -07:00
LOG ( LS_ERROR ) < < " Failed to set codec " < < spec . format . name
2016-10-20 03:27:12 -07:00
< < " to bitrate " < < bps < < " bps "
2017-04-27 02:08:52 -07:00
< < " , requires at least " < < spec . info . min_bitrate_bps
< < " bps. " ;
2016-10-20 03:27:12 -07:00
return rtc : : Optional < int > ( ) ;
2016-06-14 10:02:41 -07:00
}
2017-04-27 02:08:52 -07:00
if ( spec . info . HasFixedBitrate ( ) ) {
return rtc : : Optional < int > ( spec . info . default_bitrate_bps ) ;
} else {
// If codec is multi-rate then just set the bitrate.
return rtc : : Optional < int > ( std : : min ( bps , spec . info . max_bitrate_bps ) ) ;
}
2016-06-14 10:02:41 -07:00
}
2017-02-21 00:54:31 -08:00
} // namespace
2016-06-14 10:02:41 -07:00
2016-06-13 07:34:51 -07:00
WebRtcVoiceEngine : : WebRtcVoiceEngine (
webrtc : : AudioDeviceModule * adm ,
2017-05-02 06:46:30 -07:00
const rtc : : scoped_refptr < webrtc : : AudioEncoderFactory > & encoder_factory ,
2016-12-13 14:06:26 -08:00
const rtc : : scoped_refptr < webrtc : : AudioDecoderFactory > & decoder_factory ,
2017-06-29 08:32:09 -07:00
rtc : : scoped_refptr < webrtc : : AudioMixer > audio_mixer ,
rtc : : scoped_refptr < webrtc : : AudioProcessing > audio_processing )
2017-05-02 06:46:30 -07:00
: WebRtcVoiceEngine ( adm ,
encoder_factory ,
decoder_factory ,
audio_mixer ,
2017-06-29 08:32:09 -07:00
audio_processing ,
2017-06-15 08:29:25 -07:00
nullptr ) { }
2015-11-27 04:00:25 -08:00
2016-06-13 07:34:51 -07:00
WebRtcVoiceEngine : : WebRtcVoiceEngine (
webrtc : : AudioDeviceModule * adm ,
2017-05-02 06:46:30 -07:00
const rtc : : scoped_refptr < webrtc : : AudioEncoderFactory > & encoder_factory ,
2016-06-13 07:34:51 -07:00
const rtc : : scoped_refptr < webrtc : : AudioDecoderFactory > & decoder_factory ,
2016-12-13 14:06:26 -08:00
rtc : : scoped_refptr < webrtc : : AudioMixer > audio_mixer ,
2017-06-29 08:32:09 -07:00
rtc : : scoped_refptr < webrtc : : AudioProcessing > audio_processing ,
2016-06-13 07:34:51 -07:00
VoEWrapper * voe_wrapper )
2017-06-15 08:29:25 -07:00
: adm_ ( adm ) ,
2017-05-02 06:46:30 -07:00
encoder_factory_ ( encoder_factory ) ,
2017-04-27 02:08:52 -07:00
decoder_factory_ ( decoder_factory ) ,
2017-06-15 08:29:25 -07:00
audio_mixer_ ( audio_mixer ) ,
2017-06-29 08:32:09 -07:00
apm_ ( audio_processing ) ,
2017-04-27 02:08:52 -07:00
voe_wrapper_ ( voe_wrapper ) {
2017-06-15 08:29:25 -07:00
// This may be called from any thread, so detach thread checkers.
worker_thread_checker_ . DetachFromThread ( ) ;
signal_thread_checker_ . DetachFromThread ( ) ;
2016-03-30 23:28:51 -07:00
LOG ( LS_INFO ) < < " WebRtcVoiceEngine::WebRtcVoiceEngine " ;
2016-08-17 02:45:41 -07:00
RTC_DCHECK ( decoder_factory ) ;
2017-06-15 08:29:25 -07:00
RTC_DCHECK ( encoder_factory ) ;
2017-06-29 08:32:09 -07:00
RTC_DCHECK ( audio_processing ) ;
2017-06-15 08:29:25 -07:00
// The rest of our initialization will happen in Init.
}
2015-11-27 04:00:25 -08:00
2017-06-15 08:29:25 -07:00
WebRtcVoiceEngine : : ~ WebRtcVoiceEngine ( ) {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
LOG ( LS_INFO ) < < " WebRtcVoiceEngine::~WebRtcVoiceEngine " ;
if ( initialized_ ) {
StopAecDump ( ) ;
voe_wrapper_ - > base ( ) - > Terminate ( ) ;
webrtc : : Trace : : SetTraceCallback ( nullptr ) ;
}
}
void WebRtcVoiceEngine : : Init ( ) {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
LOG ( LS_INFO ) < < " WebRtcVoiceEngine::Init " ;
// TaskQueue expects to be created/destroyed on the same thread.
low_priority_worker_queue_ . reset (
new rtc : : TaskQueue ( " rtc-low-prio " , rtc : : TaskQueue : : Priority : : LOW ) ) ;
// VoEWrapper needs to be created on the worker thread. It's expected to be
// null here unless it's being injected for testing.
if ( ! voe_wrapper_ ) {
voe_wrapper_ . reset ( new VoEWrapper ( ) ) ;
}
2015-11-27 04:00:25 -08:00
2017-05-02 06:46:30 -07:00
// Load our audio codec lists.
2016-08-17 02:45:41 -07:00
LOG ( LS_INFO ) < < " Supported send codecs in order of preference: " ;
2017-04-27 02:08:52 -07:00
send_codecs_ = CollectCodecs ( encoder_factory_ - > GetSupportedEncoders ( ) ) ;
2016-08-17 02:45:41 -07:00
for ( const AudioCodec & codec : send_codecs_ ) {
LOG ( LS_INFO ) < < ToString ( codec ) ;
}
LOG ( LS_INFO ) < < " Supported recv codecs in order of preference: " ;
2017-04-27 02:08:52 -07:00
recv_codecs_ = CollectCodecs ( decoder_factory_ - > GetSupportedDecoders ( ) ) ;
2016-08-17 02:45:41 -07:00
for ( const AudioCodec & codec : recv_codecs_ ) {
2016-03-30 23:28:51 -07:00
LOG ( LS_INFO ) < < ToString ( codec ) ;
2014-05-02 17:33:29 +00:00
}
2016-09-07 07:34:41 -07:00
channel_config_ . enable_voice_pacing = true ;
2014-05-02 17:33:29 +00:00
2016-03-30 23:28:51 -07:00
// Temporarily turn logging level up for the Init() call.
webrtc : : Trace : : SetTraceCallback ( this ) ;
2015-11-20 16:08:07 -08:00
webrtc : : Trace : : set_level_filter ( kElevatedTraceFilter ) ;
2015-12-02 06:19:36 -08:00
LOG ( LS_INFO ) < < webrtc : : VoiceEngine : : GetVersionString ( ) ;
2017-06-29 08:32:09 -07:00
RTC_CHECK_EQ ( 0 ,
voe_wrapper_ - > base ( ) - > Init ( adm_ . get ( ) , apm ( ) , decoder_factory_ ) ) ;
2015-11-20 16:08:07 -08:00
webrtc : : Trace : : set_level_filter ( kDefaultTraceFilter ) ;
2014-05-02 17:33:29 +00:00
2016-03-30 23:28:51 -07:00
// No ADM supplied? Get the default one from VoE.
if ( ! adm_ ) {
adm_ = voe_wrapper_ - > base ( ) - > audio_device_module ( ) ;
}
RTC_DCHECK ( adm_ ) ;
2017-02-21 00:54:31 -08:00
transmit_mixer_ = voe_wrapper_ - > base ( ) - > transmit_mixer ( ) ;
RTC_DCHECK ( transmit_mixer_ ) ;
2014-05-02 17:33:29 +00:00
// Save the default AGC configuration settings. This must happen before
2015-12-08 09:50:23 -08:00
// calling ApplyOptions or the default will be overwritten.
2017-06-29 08:32:09 -07:00
default_agc_config_ = webrtc : : apm_helpers : : GetAgcConfig ( apm ( ) ) ;
2014-05-02 17:33:29 +00:00
2016-01-15 01:40:39 -08:00
// Set default engine options.
{
AudioOptions options ;
options . echo_cancellation = rtc : : Optional < bool > ( true ) ;
options . auto_gain_control = rtc : : Optional < bool > ( true ) ;
options . noise_suppression = rtc : : Optional < bool > ( true ) ;
options . highpass_filter = rtc : : Optional < bool > ( true ) ;
options . stereo_swapping = rtc : : Optional < bool > ( false ) ;
options . audio_jitter_buffer_max_packets = rtc : : Optional < int > ( 50 ) ;
options . audio_jitter_buffer_fast_accelerate = rtc : : Optional < bool > ( false ) ;
options . typing_detection = rtc : : Optional < bool > ( true ) ;
options . adjust_agc_delta = rtc : : Optional < int > ( 0 ) ;
options . experimental_agc = rtc : : Optional < bool > ( false ) ;
options . extended_filter_aec = rtc : : Optional < bool > ( false ) ;
options . delay_agnostic_aec = rtc : : Optional < bool > ( false ) ;
options . experimental_ns = rtc : : Optional < bool > ( false ) ;
2016-05-16 15:32:38 -07:00
options . intelligibility_enhancer = rtc : : Optional < bool > ( false ) ;
2016-06-30 00:02:34 -07:00
options . level_control = rtc : : Optional < bool > ( false ) ;
2016-11-15 02:34:47 -08:00
options . residual_echo_detector = rtc : : Optional < bool > ( true ) ;
2016-03-30 23:28:51 -07:00
bool error = ApplyOptions ( options ) ;
RTC_DCHECK ( error ) ;
2014-05-02 17:33:29 +00:00
}
2017-03-15 06:14:12 -07:00
// Set default audio devices.
# if !defined(WEBRTC_IOS)
webrtc : : adm_helpers : : SetRecordingDevice ( adm_ ) ;
apm ( ) - > Initialize ( ) ;
webrtc : : adm_helpers : : SetPlayoutDevice ( adm_ ) ;
# endif // !WEBRTC_IOS
2014-05-02 17:33:29 +00:00
2017-06-15 08:29:25 -07:00
// May be null for VoE injected for testing.
if ( voe ( ) - > engine ( ) ) {
2017-06-29 08:32:09 -07:00
audio_state_ = webrtc : : AudioState : : Create (
MakeAudioStateConfig ( voe ( ) , audio_mixer_ , apm_ ) ) ;
2017-06-15 08:29:25 -07:00
}
initialized_ = true ;
2014-05-02 17:33:29 +00:00
}
2015-11-06 15:34:49 -08:00
rtc : : scoped_refptr < webrtc : : AudioState >
WebRtcVoiceEngine : : GetAudioState ( ) const {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
return audio_state_ ;
}
2016-02-12 02:27:06 -08:00
VoiceMediaChannel * WebRtcVoiceEngine : : CreateChannel (
webrtc : : Call * call ,
const MediaConfig & config ,
2015-05-29 15:05:44 +02:00
const AudioOptions & options ) {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2016-02-12 02:27:06 -08:00
return new WebRtcVoiceMediaChannel ( this , config , options , call ) ;
2014-05-02 17:33:29 +00:00
}
bool WebRtcVoiceEngine : : ApplyOptions ( const AudioOptions & options_in ) {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2016-03-30 23:28:51 -07:00
LOG ( LS_INFO ) < < " WebRtcVoiceEngine::ApplyOptions: " < < options_in . ToString ( ) ;
2016-01-15 01:40:39 -08:00
AudioOptions options = options_in ; // The options are modified below.
2015-12-08 09:50:23 -08:00
2017-05-22 15:48:47 -07:00
// Set and adjust echo canceller options.
2014-05-02 17:33:29 +00:00
// kEcConference is AEC with high suppression.
webrtc : : EcModes ec_mode = webrtc : : kEcConference ;
2015-10-30 02:47:38 -07:00
if ( options . aecm_generate_comfort_noise ) {
2014-05-02 17:33:29 +00:00
LOG ( LS_VERBOSE ) < < " Comfort noise explicitly set to "
2015-10-30 02:47:38 -07:00
< < * options . aecm_generate_comfort_noise
< < " (default is false). " ;
2014-05-02 17:33:29 +00:00
}
2016-01-14 11:01:09 -08:00
# if defined(WEBRTC_IOS)
2017-05-22 15:48:47 -07:00
// On iOS, VPIO provides built-in EC.
2015-11-10 22:34:18 +01:00
options . echo_cancellation = rtc : : Optional < bool > ( false ) ;
2017-05-22 15:48:47 -07:00
options . extended_filter_aec = rtc : : Optional < bool > ( false ) ;
LOG ( LS_INFO ) < < " Always disable AEC on iOS. Use built-in instead. " ;
2014-05-02 17:33:29 +00:00
# elif defined(ANDROID)
ec_mode = webrtc : : kEcAecm ;
2015-11-10 22:34:18 +01:00
options . extended_filter_aec = rtc : : Optional < bool > ( false ) ;
2014-05-02 17:33:29 +00:00
# endif
2015-03-25 22:45:56 +01:00
// Delay Agnostic AEC automatically turns on EC if not set except on iOS
// where the feature is not supported.
bool use_delay_agnostic_aec = false ;
2016-01-14 11:01:09 -08:00
# if !defined(WEBRTC_IOS)
2015-10-30 02:47:38 -07:00
if ( options . delay_agnostic_aec ) {
use_delay_agnostic_aec = * options . delay_agnostic_aec ;
2015-03-25 22:45:56 +01:00
if ( use_delay_agnostic_aec ) {
2015-11-10 22:34:18 +01:00
options . echo_cancellation = rtc : : Optional < bool > ( true ) ;
options . extended_filter_aec = rtc : : Optional < bool > ( true ) ;
2015-03-25 22:45:56 +01:00
ec_mode = webrtc : : kEcConference ;
}
}
# endif
2017-05-22 15:48:47 -07:00
// Set and adjust noise suppressor options.
# if defined(WEBRTC_IOS)
// On iOS, VPIO provides built-in NS.
options . noise_suppression = rtc : : Optional < bool > ( false ) ;
options . typing_detection = rtc : : Optional < bool > ( false ) ;
options . experimental_ns = rtc : : Optional < bool > ( false ) ;
LOG ( LS_INFO ) < < " Always disable NS on iOS. Use built-in instead. " ;
# elif defined(ANDROID)
options . typing_detection = rtc : : Optional < bool > ( false ) ;
options . experimental_ns = rtc : : Optional < bool > ( false ) ;
# endif
// Set and adjust gain control options.
# if defined(WEBRTC_IOS)
// On iOS, VPIO provides built-in AGC.
options . auto_gain_control = rtc : : Optional < bool > ( false ) ;
options . experimental_agc = rtc : : Optional < bool > ( false ) ;
LOG ( LS_INFO ) < < " Always disable AGC on iOS. Use built-in instead. " ;
# elif defined(ANDROID)
options . experimental_agc = rtc : : Optional < bool > ( false ) ;
# endif
# if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
// Turn off the gain control if specified by the field trial. The purpose of the field trial is to reduce the amount of resampling performed inside the audio processing module on mobile platforms by whenever possible turning off the fixed AGC mode and the high-pass filter. (https://bugs.chromium.org/p/webrtc/issues/detail?id=6181).
if ( webrtc : : field_trial : : IsEnabled (
" WebRTC-Audio-MinimizeResamplingOnMobile " ) ) {
options . auto_gain_control = rtc : : Optional < bool > ( false ) ;
LOG ( LS_INFO ) < < " Disable AGC according to field trial. " ;
if ( ! ( options . noise_suppression . value_or ( false ) or
options . echo_cancellation . value_or ( false ) ) ) {
// If possible, turn off the high-pass filter.
LOG ( LS_INFO ) < < " Disable high-pass filter in response to field trial. " ;
options . highpass_filter = rtc : : Optional < bool > ( false ) ;
}
}
# endif
2016-08-26 07:16:04 -07:00
# if (WEBRTC_INTELLIGIBILITY_ENHANCER == 0)
// Hardcode the intelligibility enhancer to be off.
options . intelligibility_enhancer = rtc : : Optional < bool > ( false ) ;
# endif
2015-10-30 02:47:38 -07:00
if ( options . echo_cancellation ) {
2014-12-09 16:22:09 +00:00
// Check if platform supports built-in EC. Currently only supported on
// Android and in combination with Java based audio layer.
// TODO(henrika): investigate possibility to support built-in EC also
// in combination with Open SL ES audio.
2016-04-08 05:35:48 -07:00
const bool built_in_aec = adm ( ) - > BuiltInAECIsAvailable ( ) ;
2015-06-03 14:50:15 +02:00
if ( built_in_aec ) {
2015-05-07 07:43:17 +02:00
// Built-in EC exists on this device and use_delay_agnostic_aec is not
// overriding it. Enable/Disable it according to the echo_cancellation
// audio option.
2015-06-03 14:50:15 +02:00
const bool enable_built_in_aec =
2015-10-30 02:47:38 -07:00
* options . echo_cancellation & & ! use_delay_agnostic_aec ;
2016-04-08 05:35:48 -07:00
if ( adm ( ) - > EnableBuiltInAEC ( enable_built_in_aec ) = = 0 & &
2015-06-03 14:50:15 +02:00
enable_built_in_aec ) {
2015-03-25 22:45:56 +01:00
// Disable internal software EC if built-in EC is enabled,
2014-12-09 16:22:09 +00:00
// i.e., replace the software EC with the built-in EC.
2015-11-10 22:34:18 +01:00
options . echo_cancellation = rtc : : Optional < bool > ( false ) ;
2014-12-09 16:22:09 +00:00
LOG ( LS_INFO ) < < " Disabling EC since built-in EC will be used instead " ;
}
}
2017-02-21 00:54:31 -08:00
webrtc : : apm_helpers : : SetEcStatus (
apm ( ) , * options . echo_cancellation , ec_mode ) ;
2014-05-02 17:33:29 +00:00
# if !defined(ANDROID)
2017-02-21 00:54:31 -08:00
webrtc : : apm_helpers : : SetEcMetricsStatus ( apm ( ) , * options . echo_cancellation ) ;
2014-05-02 17:33:29 +00:00
# endif
if ( ec_mode = = webrtc : : kEcAecm ) {
2015-10-30 02:47:38 -07:00
bool cn = options . aecm_generate_comfort_noise . value_or ( false ) ;
2017-02-21 00:54:31 -08:00
webrtc : : apm_helpers : : SetAecmMode ( apm ( ) , cn ) ;
2014-05-02 17:33:29 +00:00
}
}
2015-10-30 02:47:38 -07:00
if ( options . auto_gain_control ) {
2016-08-22 12:08:55 -07:00
bool built_in_agc_avaliable = adm ( ) - > BuiltInAGCIsAvailable ( ) ;
if ( built_in_agc_avaliable ) {
2016-04-08 05:35:48 -07:00
if ( adm ( ) - > EnableBuiltInAGC ( * options . auto_gain_control ) = = 0 & &
2015-10-30 02:47:38 -07:00
* options . auto_gain_control ) {
2015-09-23 14:08:33 +02:00
// Disable internal software AGC if built-in AGC is enabled,
// i.e., replace the software AGC with the built-in AGC.
2015-11-10 22:34:18 +01:00
options . auto_gain_control = rtc : : Optional < bool > ( false ) ;
2015-09-23 14:08:33 +02:00
LOG ( LS_INFO ) < < " Disabling AGC since built-in AGC will be used instead " ;
}
}
2017-03-16 01:20:23 -07:00
webrtc : : apm_helpers : : SetAgcStatus ( apm ( ) , adm ( ) , * options . auto_gain_control ) ;
2014-05-02 17:33:29 +00:00
}
2015-10-30 02:47:38 -07:00
if ( options . tx_agc_target_dbov | | options . tx_agc_digital_compression_gain | |
2017-02-21 00:54:31 -08:00
options . tx_agc_limiter | | options . adjust_agc_delta ) {
2014-05-02 17:33:29 +00:00
// Override default_agc_config_. Generally, an unset option means "leave
// the VoE bits alone" in this function, so we want whatever is set to be
// stored as the new "default". If we didn't, then setting e.g.
// tx_agc_target_dbov would reset digital compression gain and limiter
// settings.
// Also, if we don't update default_agc_config_, then adjust_agc_delta
// would be an offset from the original values, and not whatever was set
// explicitly.
2015-10-30 02:47:38 -07:00
default_agc_config_ . targetLeveldBOv = options . tx_agc_target_dbov . value_or (
default_agc_config_ . targetLeveldBOv ) ;
2014-05-02 17:33:29 +00:00
default_agc_config_ . digitalCompressionGaindB =
2015-10-30 02:47:38 -07:00
options . tx_agc_digital_compression_gain . value_or (
2014-05-02 17:33:29 +00:00
default_agc_config_ . digitalCompressionGaindB ) ;
default_agc_config_ . limiterEnable =
2015-10-30 02:47:38 -07:00
options . tx_agc_limiter . value_or ( default_agc_config_ . limiterEnable ) ;
2017-02-21 00:54:31 -08:00
webrtc : : AgcConfig config = default_agc_config_ ;
if ( options . adjust_agc_delta ) {
config . targetLeveldBOv - = * options . adjust_agc_delta ;
LOG ( LS_INFO ) < < " Adjusting AGC level from default - "
< < default_agc_config_ . targetLeveldBOv < < " dB to - "
< < config . targetLeveldBOv < < " dB " ;
2014-05-02 17:33:29 +00:00
}
2017-06-29 08:32:09 -07:00
webrtc : : apm_helpers : : SetAgcConfig ( apm ( ) , config ) ;
2014-05-02 17:33:29 +00:00
}
2016-05-16 15:32:38 -07:00
if ( options . intelligibility_enhancer ) {
intelligibility_enhancer_ = options . intelligibility_enhancer ;
}
if ( intelligibility_enhancer_ & & * intelligibility_enhancer_ ) {
LOG ( LS_INFO ) < < " Enabling NS when Intelligibility Enhancer is active. " ;
options . noise_suppression = intelligibility_enhancer_ ;
}
2015-10-30 02:47:38 -07:00
if ( options . noise_suppression ) {
2016-05-16 15:32:38 -07:00
if ( adm ( ) - > BuiltInNSIsAvailable ( ) ) {
bool builtin_ns =
* options . noise_suppression & &
! ( intelligibility_enhancer_ & & * intelligibility_enhancer_ ) ;
if ( adm ( ) - > EnableBuiltInNS ( builtin_ns ) = = 0 & & builtin_ns ) {
2015-09-23 14:08:33 +02:00
// Disable internal software NS if built-in NS is enabled,
// i.e., replace the software NS with the built-in NS.
2015-11-10 22:34:18 +01:00
options . noise_suppression = rtc : : Optional < bool > ( false ) ;
2015-09-23 14:08:33 +02:00
LOG ( LS_INFO ) < < " Disabling NS since built-in NS will be used instead " ;
}
}
2017-02-21 00:54:31 -08:00
webrtc : : apm_helpers : : SetNsStatus ( apm ( ) , * options . noise_suppression ) ;
2014-05-02 17:33:29 +00:00
}
2015-10-30 02:47:38 -07:00
if ( options . stereo_swapping ) {
LOG ( LS_INFO ) < < " Stereo swapping enabled? " < < * options . stereo_swapping ;
2017-02-21 00:54:31 -08:00
transmit_mixer ( ) - > EnableStereoChannelSwapping ( * options . stereo_swapping ) ;
2014-05-02 17:33:29 +00:00
}
2015-10-30 02:47:38 -07:00
if ( options . audio_jitter_buffer_max_packets ) {
LOG ( LS_INFO ) < < " NetEq capacity is "
< < * options . audio_jitter_buffer_max_packets ;
2016-09-07 07:34:41 -07:00
channel_config_ . acm_config . neteq_config . max_packets_in_buffer =
std : : max ( 20 , * options . audio_jitter_buffer_max_packets ) ;
2015-05-11 12:44:23 +02:00
}
2015-10-30 02:47:38 -07:00
if ( options . audio_jitter_buffer_fast_accelerate ) {
LOG ( LS_INFO ) < < " NetEq fast mode? "
< < * options . audio_jitter_buffer_fast_accelerate ;
2016-09-07 07:34:41 -07:00
channel_config_ . acm_config . neteq_config . enable_fast_accelerate =
* options . audio_jitter_buffer_fast_accelerate ;
2015-06-01 10:29:41 +02:00
}
2015-10-30 02:47:38 -07:00
if ( options . typing_detection ) {
LOG ( LS_INFO ) < < " Typing detection is enabled? "
< < * options . typing_detection ;
2017-02-21 00:54:31 -08:00
webrtc : : apm_helpers : : SetTypingDetectionStatus (
apm ( ) , * options . typing_detection ) ;
2014-05-02 17:33:29 +00:00
}
2014-08-28 10:52:44 +00:00
webrtc : : Config config ;
2015-10-30 02:47:38 -07:00
if ( options . delay_agnostic_aec )
delay_agnostic_aec_ = options . delay_agnostic_aec ;
if ( delay_agnostic_aec_ ) {
LOG ( LS_INFO ) < < " Delay agnostic aec is enabled? " < < * delay_agnostic_aec_ ;
2015-07-02 00:17:55 -07:00
config . Set < webrtc : : DelayAgnostic > (
2015-10-30 02:47:38 -07:00
new webrtc : : DelayAgnostic ( * delay_agnostic_aec_ ) ) ;
2015-03-25 22:45:56 +01:00
}
2015-10-30 02:47:38 -07:00
if ( options . extended_filter_aec ) {
extended_filter_aec_ = options . extended_filter_aec ;
}
if ( extended_filter_aec_ ) {
LOG ( LS_INFO ) < < " Extended filter aec is enabled? " < < * extended_filter_aec_ ;
2015-06-09 16:03:13 +02:00
config . Set < webrtc : : ExtendedFilter > (
2015-10-30 02:47:38 -07:00
new webrtc : : ExtendedFilter ( * extended_filter_aec_ ) ) ;
2014-08-28 10:52:44 +00:00
}
2015-10-30 02:47:38 -07:00
if ( options . experimental_ns ) {
experimental_ns_ = options . experimental_ns ;
}
if ( experimental_ns_ ) {
LOG ( LS_INFO ) < < " Experimental ns is enabled? " < < * experimental_ns_ ;
2014-08-28 10:52:44 +00:00
config . Set < webrtc : : ExperimentalNs > (
2015-10-30 02:47:38 -07:00
new webrtc : : ExperimentalNs ( * experimental_ns_ ) ) ;
2014-08-28 10:52:44 +00:00
}
2016-05-16 15:32:38 -07:00
if ( intelligibility_enhancer_ ) {
LOG ( LS_INFO ) < < " Intelligibility Enhancer is enabled? "
< < * intelligibility_enhancer_ ;
config . Set < webrtc : : Intelligibility > (
new webrtc : : Intelligibility ( * intelligibility_enhancer_ ) ) ;
}
2016-06-30 00:02:34 -07:00
if ( options . level_control ) {
level_control_ = options . level_control ;
}
2017-07-25 15:45:24 -07:00
webrtc : : AudioProcessing : : Config apm_config = apm ( ) - > GetConfig ( ) ;
2016-06-30 00:02:34 -07:00
LOG ( LS_INFO ) < < " Level control: "
< < ( ! ! level_control_ ? * level_control_ : - 1 ) ;
if ( level_control_ ) {
2017-07-25 15:45:24 -07:00
apm_config . level_controller . enabled = * level_control_ ;
2016-10-20 01:53:27 -07:00
if ( options . level_control_initial_peak_level_dbfs ) {
2017-07-25 15:45:24 -07:00
apm_config . level_controller . initial_peak_level_dbfs =
2016-10-20 01:53:27 -07:00
* options . level_control_initial_peak_level_dbfs ;
}
2016-06-30 00:02:34 -07:00
}
2016-11-22 07:24:52 -08:00
if ( options . highpass_filter ) {
2017-07-25 15:45:24 -07:00
apm_config . high_pass_filter . enabled = * options . highpass_filter ;
2016-11-22 07:24:52 -08:00
}
2017-02-10 05:11:09 -08:00
if ( options . residual_echo_detector ) {
2017-07-25 15:45:24 -07:00
apm_config . residual_echo_detector . enabled = * options . residual_echo_detector ;
2017-02-10 05:11:09 -08:00
}
2016-10-26 05:12:24 -07:00
apm ( ) - > SetExtraOptions ( config ) ;
2017-07-25 15:45:24 -07:00
apm ( ) - > ApplyConfig ( apm_config ) ;
2014-08-28 10:52:44 +00:00
2015-10-30 02:47:38 -07:00
if ( options . recording_sample_rate ) {
LOG ( LS_INFO ) < < " Recording sample rate is "
< < * options . recording_sample_rate ;
2016-04-08 05:35:48 -07:00
if ( adm ( ) - > SetRecordingSampleRate ( * options . recording_sample_rate ) ) {
2015-10-30 02:47:38 -07:00
LOG_RTCERR1 ( SetRecordingSampleRate , * options . recording_sample_rate ) ;
2014-05-02 17:33:29 +00:00
}
}
2015-10-30 02:47:38 -07:00
if ( options . playout_sample_rate ) {
LOG ( LS_INFO ) < < " Playout sample rate is " < < * options . playout_sample_rate ;
2016-04-08 05:35:48 -07:00
if ( adm ( ) - > SetPlayoutSampleRate ( * options . playout_sample_rate ) ) {
2015-10-30 02:47:38 -07:00
LOG_RTCERR1 ( SetPlayoutSampleRate , * options . playout_sample_rate ) ;
2014-05-02 17:33:29 +00:00
}
}
return true ;
}
2017-03-01 17:02:23 -08:00
// TODO(solenberg): Remove, once AudioMonitor is gone.
2013-07-10 00:45:36 +00:00
int WebRtcVoiceEngine : : GetInputLevel ( ) {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2017-03-01 17:02:23 -08:00
int8_t level = transmit_mixer ( ) - > AudioLevel ( ) ;
RTC_DCHECK_LE ( 0 , level ) ;
return level ;
2013-07-10 00:45:36 +00:00
}
2016-06-14 07:12:39 -07:00
const std : : vector < AudioCodec > & WebRtcVoiceEngine : : send_codecs ( ) const {
RTC_DCHECK ( signal_thread_checker_ . CalledOnValidThread ( ) ) ;
2016-08-17 02:45:41 -07:00
return send_codecs_ ;
2016-06-14 07:12:39 -07:00
}
const std : : vector < AudioCodec > & WebRtcVoiceEngine : : recv_codecs ( ) const {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( signal_thread_checker_ . CalledOnValidThread ( ) ) ;
2016-08-17 02:45:41 -07:00
return recv_codecs_ ;
2013-07-10 00:45:36 +00:00
}
2015-12-07 10:45:43 +01:00
RtpCapabilities WebRtcVoiceEngine : : GetCapabilities ( ) const {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( signal_thread_checker_ . CalledOnValidThread ( ) ) ;
2015-12-07 10:45:43 +01:00
RtpCapabilities capabilities ;
capabilities . header_extensions . push_back (
2016-05-26 11:24:55 -07:00
webrtc : : RtpExtension ( webrtc : : RtpExtension : : kAudioLevelUri ,
webrtc : : RtpExtension : : kAudioLevelDefaultId ) ) ;
2017-02-28 08:50:47 -08:00
if ( webrtc : : field_trial : : IsEnabled ( " WebRTC-Audio-SendSideBwe " ) ) {
2016-05-26 11:24:55 -07:00
capabilities . header_extensions . push_back ( webrtc : : RtpExtension (
webrtc : : RtpExtension : : kTransportSequenceNumberUri ,
webrtc : : RtpExtension : : kTransportSequenceNumberDefaultId ) ) ;
2016-02-04 04:12:24 -08:00
}
2015-12-07 10:45:43 +01:00
return capabilities ;
2013-07-10 00:45:36 +00:00
}
int WebRtcVoiceEngine : : GetLastEngineError ( ) {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2013-07-10 00:45:36 +00:00
return voe_wrapper_ - > error ( ) ;
}
void WebRtcVoiceEngine : : Print ( webrtc : : TraceLevel level , const char * trace ,
int length ) {
2015-11-06 15:34:49 -08:00
// Note: This callback can happen on any thread!
2014-07-29 17:36:52 +00:00
rtc : : LoggingSeverity sev = rtc : : LS_VERBOSE ;
2013-07-10 00:45:36 +00:00
if ( level = = webrtc : : kTraceError | | level = = webrtc : : kTraceCritical )
2014-07-29 17:36:52 +00:00
sev = rtc : : LS_ERROR ;
2013-07-10 00:45:36 +00:00
else if ( level = = webrtc : : kTraceWarning )
2014-07-29 17:36:52 +00:00
sev = rtc : : LS_WARNING ;
2013-07-10 00:45:36 +00:00
else if ( level = = webrtc : : kTraceStateInfo | | level = = webrtc : : kTraceInfo )
2014-07-29 17:36:52 +00:00
sev = rtc : : LS_INFO ;
2013-07-10 00:45:36 +00:00
else if ( level = = webrtc : : kTraceTerseInfo )
2014-07-29 17:36:52 +00:00
sev = rtc : : LS_INFO ;
2013-07-10 00:45:36 +00:00
2016-03-08 06:35:16 -08:00
// Skip past boilerplate prefix text.
2013-07-10 00:45:36 +00:00
if ( length < 72 ) {
std : : string msg ( trace , length ) ;
LOG ( LS_ERROR ) < < " Malformed webrtc log message: " ;
LOG_V ( sev ) < < msg ;
} else {
std : : string msg ( trace + 71 , length - 72 ) ;
2015-09-23 13:24:32 +02:00
LOG_V ( sev ) < < " webrtc: " < < msg ;
2013-07-10 00:45:36 +00:00
}
}
2015-09-29 06:06:31 -07:00
void WebRtcVoiceEngine : : RegisterChannel ( WebRtcVoiceMediaChannel * channel ) {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
RTC_DCHECK ( channel ) ;
2013-07-10 00:45:36 +00:00
channels_ . push_back ( channel ) ;
}
2015-09-29 06:06:31 -07:00
void WebRtcVoiceEngine : : UnregisterChannel ( WebRtcVoiceMediaChannel * channel ) {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2015-09-29 06:06:31 -07:00
auto it = std : : find ( channels_ . begin ( ) , channels_ . end ( ) , channel ) ;
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( it ! = channels_ . end ( ) ) ;
channels_ . erase ( it ) ;
2013-07-10 00:45:36 +00:00
}
2016-01-15 03:06:36 -08:00
bool WebRtcVoiceEngine : : StartAecDump ( rtc : : PlatformFile file ,
int64_t max_size_bytes ) {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2017-06-15 08:29:25 -07:00
auto aec_dump = webrtc : : AecDumpFactory : : Create (
file , max_size_bytes , low_priority_worker_queue_ . get ( ) ) ;
Reland of Activate 'offload debug dump recordings from audio thread to TaskQueue'. (patchset #1 id:1 of https://codereview.webrtc.org/2910633002/ )
Reason for revert:
Revert of revert of revert of revert of 'Activating..'. Or "reland of reland of 'Activate..'".
*Now* the internal projects are fixed and the fix is verified.
Original issue's description:
> Revert of Activate 'offload debug dump recordings from audio thread to TaskQueue'. (patchset #1 id:1 of https://codereview.webrtc.org/2903153005/ )
>
> Reason for revert:
> Reverting again: internal project issues were apparently not completely fixed.
>
> Original issue's description:
> > Reland of Activate 'offload debug dump recordings from audio thread to TaskQueue'. (patchset #1 id:1 of https://codereview.webrtc.org/2904893002/ )
> >
> > Reason for revert:
> > Revert the revert now that internal projects are updated.
> >
> > Original issue's description:
> > > Revert of Activate 'offload debug dump recordings from audio thread to TaskQueue'. (patchset #4 id:160001 of https://codereview.webrtc.org/2896813002/ )
> > >
> > > Reason for revert:
> > > Breaks internal project.
> > >
> > > Original issue's description:
> > > > Activate 'offload debug dump recordings from audio thread to TaskQueue'.
> > > >
> > > > A low priority task queue is added to WebRTCVoiceEngine. The
> > > > start/stop debug calls make file logging happen on the task queue.
> > > >
> > > > In a dependent CL (https://codereview.webrtc.org/2888303003), the task queue is moved to PeerConnectionFactory,
> > > > so that it can be shared for low priority tasks between different
> > > > subcomponents. It will require some changes to MediaEngine,
> > > > CompositeMediaEngine, WebRTCVoiceEngine, and changes in internal
> > > > projects.
> > > >
> > > > A task queue must be created and destroyed from the same thread. With
> > > > this CL that will be the worker thread, which creates and destroys
> > > > WebRTCVoiceEngine. With the dependent CL, it will probably change to
> > > > the signaling thread.
> > > >
> > > > NOTRY=True # tests just passed
> > > >
> > > > BUG=webrtc:7404
> > > >
> > > > Review-Url: https://codereview.webrtc.org/2896813002
> > > > Cr-Commit-Position: refs/heads/master@{#18252}
> > > > Committed: https://chromium.googlesource.com/external/webrtc/+/c61bf947b4ac31f3500858ffcae6fee39d799930
> > >
> > > TBR=solenberg@webrtc.org,tommi@webrtc.org,perkj@webrtc.org,danilchap@webrtc.org,tommi@chromium.org
> > > # Skipping CQ checks because original CL landed less than 1 days ago.
> > > NOPRESUBMIT=true
> > > NOTREECHECKS=true
> > > NOTRY=true
> > > BUG=webrtc:7404
> > >
> > > Review-Url: https://codereview.webrtc.org/2904893002
> > > Cr-Commit-Position: refs/heads/master@{#18255}
> > > Committed: https://chromium.googlesource.com/external/webrtc/+/be68b72cfad0686dcd892bba1368b199a7ee16ca
> >
> > TBR=solenberg@webrtc.org,tommi@webrtc.org,perkj@webrtc.org,danilchap@webrtc.org,tommi@chromium.org
> > # Not skipping CQ checks because original CL landed more than 1 days ago.
> > BUG=webrtc:7404
> >
> > Review-Url: https://codereview.webrtc.org/2903153005
> > Cr-Commit-Position: refs/heads/master@{#18270}
> > Committed: https://chromium.googlesource.com/external/webrtc/+/d2303a2338106feab684860f1c133877b46bdd4f
>
> TBR=solenberg@webrtc.org,tommi@webrtc.org,perkj@webrtc.org,danilchap@webrtc.org,tommi@chromium.org
> # Skipping CQ checks because original CL landed less than 1 days ago.
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:7404
>
> Review-Url: https://codereview.webrtc.org/2910633002
> Cr-Commit-Position: refs/heads/master@{#18272}
> Committed: https://chromium.googlesource.com/external/webrtc/+/fe9ecb07ea8254d8a09605f25203a4d045b3ffee
TBR=solenberg@webrtc.org,tommi@webrtc.org,perkj@webrtc.org,danilchap@webrtc.org,tommi@chromium.org
# Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=webrtc:7404
Review-Url: https://codereview.webrtc.org/2904423002
Cr-Commit-Position: refs/heads/master@{#18300}
2017-05-29 02:56:27 -07:00
if ( ! aec_dump ) {
2014-01-23 22:12:45 +00:00
return false ;
}
Reland of Activate 'offload debug dump recordings from audio thread to TaskQueue'. (patchset #1 id:1 of https://codereview.webrtc.org/2910633002/ )
Reason for revert:
Revert of revert of revert of revert of 'Activating..'. Or "reland of reland of 'Activate..'".
*Now* the internal projects are fixed and the fix is verified.
Original issue's description:
> Revert of Activate 'offload debug dump recordings from audio thread to TaskQueue'. (patchset #1 id:1 of https://codereview.webrtc.org/2903153005/ )
>
> Reason for revert:
> Reverting again: internal project issues were apparently not completely fixed.
>
> Original issue's description:
> > Reland of Activate 'offload debug dump recordings from audio thread to TaskQueue'. (patchset #1 id:1 of https://codereview.webrtc.org/2904893002/ )
> >
> > Reason for revert:
> > Revert the revert now that internal projects are updated.
> >
> > Original issue's description:
> > > Revert of Activate 'offload debug dump recordings from audio thread to TaskQueue'. (patchset #4 id:160001 of https://codereview.webrtc.org/2896813002/ )
> > >
> > > Reason for revert:
> > > Breaks internal project.
> > >
> > > Original issue's description:
> > > > Activate 'offload debug dump recordings from audio thread to TaskQueue'.
> > > >
> > > > A low priority task queue is added to WebRTCVoiceEngine. The
> > > > start/stop debug calls make file logging happen on the task queue.
> > > >
> > > > In a dependent CL (https://codereview.webrtc.org/2888303003), the task queue is moved to PeerConnectionFactory,
> > > > so that it can be shared for low priority tasks between different
> > > > subcomponents. It will require some changes to MediaEngine,
> > > > CompositeMediaEngine, WebRTCVoiceEngine, and changes in internal
> > > > projects.
> > > >
> > > > A task queue must be created and destroyed from the same thread. With
> > > > this CL that will be the worker thread, which creates and destroys
> > > > WebRTCVoiceEngine. With the dependent CL, it will probably change to
> > > > the signaling thread.
> > > >
> > > > NOTRY=True # tests just passed
> > > >
> > > > BUG=webrtc:7404
> > > >
> > > > Review-Url: https://codereview.webrtc.org/2896813002
> > > > Cr-Commit-Position: refs/heads/master@{#18252}
> > > > Committed: https://chromium.googlesource.com/external/webrtc/+/c61bf947b4ac31f3500858ffcae6fee39d799930
> > >
> > > TBR=solenberg@webrtc.org,tommi@webrtc.org,perkj@webrtc.org,danilchap@webrtc.org,tommi@chromium.org
> > > # Skipping CQ checks because original CL landed less than 1 days ago.
> > > NOPRESUBMIT=true
> > > NOTREECHECKS=true
> > > NOTRY=true
> > > BUG=webrtc:7404
> > >
> > > Review-Url: https://codereview.webrtc.org/2904893002
> > > Cr-Commit-Position: refs/heads/master@{#18255}
> > > Committed: https://chromium.googlesource.com/external/webrtc/+/be68b72cfad0686dcd892bba1368b199a7ee16ca
> >
> > TBR=solenberg@webrtc.org,tommi@webrtc.org,perkj@webrtc.org,danilchap@webrtc.org,tommi@chromium.org
> > # Not skipping CQ checks because original CL landed more than 1 days ago.
> > BUG=webrtc:7404
> >
> > Review-Url: https://codereview.webrtc.org/2903153005
> > Cr-Commit-Position: refs/heads/master@{#18270}
> > Committed: https://chromium.googlesource.com/external/webrtc/+/d2303a2338106feab684860f1c133877b46bdd4f
>
> TBR=solenberg@webrtc.org,tommi@webrtc.org,perkj@webrtc.org,danilchap@webrtc.org,tommi@chromium.org
> # Skipping CQ checks because original CL landed less than 1 days ago.
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:7404
>
> Review-Url: https://codereview.webrtc.org/2910633002
> Cr-Commit-Position: refs/heads/master@{#18272}
> Committed: https://chromium.googlesource.com/external/webrtc/+/fe9ecb07ea8254d8a09605f25203a4d045b3ffee
TBR=solenberg@webrtc.org,tommi@webrtc.org,perkj@webrtc.org,danilchap@webrtc.org,tommi@chromium.org
# Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=webrtc:7404
Review-Url: https://codereview.webrtc.org/2904423002
Cr-Commit-Position: refs/heads/master@{#18300}
2017-05-29 02:56:27 -07:00
apm ( ) - > AttachAecDump ( std : : move ( aec_dump ) ) ;
2013-12-13 00:21:03 +00:00
return true ;
}
2013-07-10 00:45:36 +00:00
void WebRtcVoiceEngine : : StartAecDump ( const std : : string & filename ) {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
Reland of Activate 'offload debug dump recordings from audio thread to TaskQueue'. (patchset #1 id:1 of https://codereview.webrtc.org/2910633002/ )
Reason for revert:
Revert of revert of revert of revert of 'Activating..'. Or "reland of reland of 'Activate..'".
*Now* the internal projects are fixed and the fix is verified.
Original issue's description:
> Revert of Activate 'offload debug dump recordings from audio thread to TaskQueue'. (patchset #1 id:1 of https://codereview.webrtc.org/2903153005/ )
>
> Reason for revert:
> Reverting again: internal project issues were apparently not completely fixed.
>
> Original issue's description:
> > Reland of Activate 'offload debug dump recordings from audio thread to TaskQueue'. (patchset #1 id:1 of https://codereview.webrtc.org/2904893002/ )
> >
> > Reason for revert:
> > Revert the revert now that internal projects are updated.
> >
> > Original issue's description:
> > > Revert of Activate 'offload debug dump recordings from audio thread to TaskQueue'. (patchset #4 id:160001 of https://codereview.webrtc.org/2896813002/ )
> > >
> > > Reason for revert:
> > > Breaks internal project.
> > >
> > > Original issue's description:
> > > > Activate 'offload debug dump recordings from audio thread to TaskQueue'.
> > > >
> > > > A low priority task queue is added to WebRTCVoiceEngine. The
> > > > start/stop debug calls make file logging happen on the task queue.
> > > >
> > > > In a dependent CL (https://codereview.webrtc.org/2888303003), the task queue is moved to PeerConnectionFactory,
> > > > so that it can be shared for low priority tasks between different
> > > > subcomponents. It will require some changes to MediaEngine,
> > > > CompositeMediaEngine, WebRTCVoiceEngine, and changes in internal
> > > > projects.
> > > >
> > > > A task queue must be created and destroyed from the same thread. With
> > > > this CL that will be the worker thread, which creates and destroys
> > > > WebRTCVoiceEngine. With the dependent CL, it will probably change to
> > > > the signaling thread.
> > > >
> > > > NOTRY=True # tests just passed
> > > >
> > > > BUG=webrtc:7404
> > > >
> > > > Review-Url: https://codereview.webrtc.org/2896813002
> > > > Cr-Commit-Position: refs/heads/master@{#18252}
> > > > Committed: https://chromium.googlesource.com/external/webrtc/+/c61bf947b4ac31f3500858ffcae6fee39d799930
> > >
> > > TBR=solenberg@webrtc.org,tommi@webrtc.org,perkj@webrtc.org,danilchap@webrtc.org,tommi@chromium.org
> > > # Skipping CQ checks because original CL landed less than 1 days ago.
> > > NOPRESUBMIT=true
> > > NOTREECHECKS=true
> > > NOTRY=true
> > > BUG=webrtc:7404
> > >
> > > Review-Url: https://codereview.webrtc.org/2904893002
> > > Cr-Commit-Position: refs/heads/master@{#18255}
> > > Committed: https://chromium.googlesource.com/external/webrtc/+/be68b72cfad0686dcd892bba1368b199a7ee16ca
> >
> > TBR=solenberg@webrtc.org,tommi@webrtc.org,perkj@webrtc.org,danilchap@webrtc.org,tommi@chromium.org
> > # Not skipping CQ checks because original CL landed more than 1 days ago.
> > BUG=webrtc:7404
> >
> > Review-Url: https://codereview.webrtc.org/2903153005
> > Cr-Commit-Position: refs/heads/master@{#18270}
> > Committed: https://chromium.googlesource.com/external/webrtc/+/d2303a2338106feab684860f1c133877b46bdd4f
>
> TBR=solenberg@webrtc.org,tommi@webrtc.org,perkj@webrtc.org,danilchap@webrtc.org,tommi@chromium.org
> # Skipping CQ checks because original CL landed less than 1 days ago.
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:7404
>
> Review-Url: https://codereview.webrtc.org/2910633002
> Cr-Commit-Position: refs/heads/master@{#18272}
> Committed: https://chromium.googlesource.com/external/webrtc/+/fe9ecb07ea8254d8a09605f25203a4d045b3ffee
TBR=solenberg@webrtc.org,tommi@webrtc.org,perkj@webrtc.org,danilchap@webrtc.org,tommi@chromium.org
# Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=webrtc:7404
Review-Url: https://codereview.webrtc.org/2904423002
Cr-Commit-Position: refs/heads/master@{#18300}
2017-05-29 02:56:27 -07:00
2017-06-15 08:29:25 -07:00
auto aec_dump = webrtc : : AecDumpFactory : : Create (
filename , - 1 , low_priority_worker_queue_ . get ( ) ) ;
Reland of Activate 'offload debug dump recordings from audio thread to TaskQueue'. (patchset #1 id:1 of https://codereview.webrtc.org/2910633002/ )
Reason for revert:
Revert of revert of revert of revert of 'Activating..'. Or "reland of reland of 'Activate..'".
*Now* the internal projects are fixed and the fix is verified.
Original issue's description:
> Revert of Activate 'offload debug dump recordings from audio thread to TaskQueue'. (patchset #1 id:1 of https://codereview.webrtc.org/2903153005/ )
>
> Reason for revert:
> Reverting again: internal project issues were apparently not completely fixed.
>
> Original issue's description:
> > Reland of Activate 'offload debug dump recordings from audio thread to TaskQueue'. (patchset #1 id:1 of https://codereview.webrtc.org/2904893002/ )
> >
> > Reason for revert:
> > Revert the revert now that internal projects are updated.
> >
> > Original issue's description:
> > > Revert of Activate 'offload debug dump recordings from audio thread to TaskQueue'. (patchset #4 id:160001 of https://codereview.webrtc.org/2896813002/ )
> > >
> > > Reason for revert:
> > > Breaks internal project.
> > >
> > > Original issue's description:
> > > > Activate 'offload debug dump recordings from audio thread to TaskQueue'.
> > > >
> > > > A low priority task queue is added to WebRTCVoiceEngine. The
> > > > start/stop debug calls make file logging happen on the task queue.
> > > >
> > > > In a dependent CL (https://codereview.webrtc.org/2888303003), the task queue is moved to PeerConnectionFactory,
> > > > so that it can be shared for low priority tasks between different
> > > > subcomponents. It will require some changes to MediaEngine,
> > > > CompositeMediaEngine, WebRTCVoiceEngine, and changes in internal
> > > > projects.
> > > >
> > > > A task queue must be created and destroyed from the same thread. With
> > > > this CL that will be the worker thread, which creates and destroys
> > > > WebRTCVoiceEngine. With the dependent CL, it will probably change to
> > > > the signaling thread.
> > > >
> > > > NOTRY=True # tests just passed
> > > >
> > > > BUG=webrtc:7404
> > > >
> > > > Review-Url: https://codereview.webrtc.org/2896813002
> > > > Cr-Commit-Position: refs/heads/master@{#18252}
> > > > Committed: https://chromium.googlesource.com/external/webrtc/+/c61bf947b4ac31f3500858ffcae6fee39d799930
> > >
> > > TBR=solenberg@webrtc.org,tommi@webrtc.org,perkj@webrtc.org,danilchap@webrtc.org,tommi@chromium.org
> > > # Skipping CQ checks because original CL landed less than 1 days ago.
> > > NOPRESUBMIT=true
> > > NOTREECHECKS=true
> > > NOTRY=true
> > > BUG=webrtc:7404
> > >
> > > Review-Url: https://codereview.webrtc.org/2904893002
> > > Cr-Commit-Position: refs/heads/master@{#18255}
> > > Committed: https://chromium.googlesource.com/external/webrtc/+/be68b72cfad0686dcd892bba1368b199a7ee16ca
> >
> > TBR=solenberg@webrtc.org,tommi@webrtc.org,perkj@webrtc.org,danilchap@webrtc.org,tommi@chromium.org
> > # Not skipping CQ checks because original CL landed more than 1 days ago.
> > BUG=webrtc:7404
> >
> > Review-Url: https://codereview.webrtc.org/2903153005
> > Cr-Commit-Position: refs/heads/master@{#18270}
> > Committed: https://chromium.googlesource.com/external/webrtc/+/d2303a2338106feab684860f1c133877b46bdd4f
>
> TBR=solenberg@webrtc.org,tommi@webrtc.org,perkj@webrtc.org,danilchap@webrtc.org,tommi@chromium.org
> # Skipping CQ checks because original CL landed less than 1 days ago.
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:7404
>
> Review-Url: https://codereview.webrtc.org/2910633002
> Cr-Commit-Position: refs/heads/master@{#18272}
> Committed: https://chromium.googlesource.com/external/webrtc/+/fe9ecb07ea8254d8a09605f25203a4d045b3ffee
TBR=solenberg@webrtc.org,tommi@webrtc.org,perkj@webrtc.org,danilchap@webrtc.org,tommi@chromium.org
# Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=webrtc:7404
Review-Url: https://codereview.webrtc.org/2904423002
Cr-Commit-Position: refs/heads/master@{#18300}
2017-05-29 02:56:27 -07:00
if ( aec_dump ) {
apm ( ) - > AttachAecDump ( std : : move ( aec_dump ) ) ;
2013-07-10 00:45:36 +00:00
}
}
void WebRtcVoiceEngine : : StopAecDump ( ) {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
Reland of Activate 'offload debug dump recordings from audio thread to TaskQueue'. (patchset #1 id:1 of https://codereview.webrtc.org/2910633002/ )
Reason for revert:
Revert of revert of revert of revert of 'Activating..'. Or "reland of reland of 'Activate..'".
*Now* the internal projects are fixed and the fix is verified.
Original issue's description:
> Revert of Activate 'offload debug dump recordings from audio thread to TaskQueue'. (patchset #1 id:1 of https://codereview.webrtc.org/2903153005/ )
>
> Reason for revert:
> Reverting again: internal project issues were apparently not completely fixed.
>
> Original issue's description:
> > Reland of Activate 'offload debug dump recordings from audio thread to TaskQueue'. (patchset #1 id:1 of https://codereview.webrtc.org/2904893002/ )
> >
> > Reason for revert:
> > Revert the revert now that internal projects are updated.
> >
> > Original issue's description:
> > > Revert of Activate 'offload debug dump recordings from audio thread to TaskQueue'. (patchset #4 id:160001 of https://codereview.webrtc.org/2896813002/ )
> > >
> > > Reason for revert:
> > > Breaks internal project.
> > >
> > > Original issue's description:
> > > > Activate 'offload debug dump recordings from audio thread to TaskQueue'.
> > > >
> > > > A low priority task queue is added to WebRTCVoiceEngine. The
> > > > start/stop debug calls make file logging happen on the task queue.
> > > >
> > > > In a dependent CL (https://codereview.webrtc.org/2888303003), the task queue is moved to PeerConnectionFactory,
> > > > so that it can be shared for low priority tasks between different
> > > > subcomponents. It will require some changes to MediaEngine,
> > > > CompositeMediaEngine, WebRTCVoiceEngine, and changes in internal
> > > > projects.
> > > >
> > > > A task queue must be created and destroyed from the same thread. With
> > > > this CL that will be the worker thread, which creates and destroys
> > > > WebRTCVoiceEngine. With the dependent CL, it will probably change to
> > > > the signaling thread.
> > > >
> > > > NOTRY=True # tests just passed
> > > >
> > > > BUG=webrtc:7404
> > > >
> > > > Review-Url: https://codereview.webrtc.org/2896813002
> > > > Cr-Commit-Position: refs/heads/master@{#18252}
> > > > Committed: https://chromium.googlesource.com/external/webrtc/+/c61bf947b4ac31f3500858ffcae6fee39d799930
> > >
> > > TBR=solenberg@webrtc.org,tommi@webrtc.org,perkj@webrtc.org,danilchap@webrtc.org,tommi@chromium.org
> > > # Skipping CQ checks because original CL landed less than 1 days ago.
> > > NOPRESUBMIT=true
> > > NOTREECHECKS=true
> > > NOTRY=true
> > > BUG=webrtc:7404
> > >
> > > Review-Url: https://codereview.webrtc.org/2904893002
> > > Cr-Commit-Position: refs/heads/master@{#18255}
> > > Committed: https://chromium.googlesource.com/external/webrtc/+/be68b72cfad0686dcd892bba1368b199a7ee16ca
> >
> > TBR=solenberg@webrtc.org,tommi@webrtc.org,perkj@webrtc.org,danilchap@webrtc.org,tommi@chromium.org
> > # Not skipping CQ checks because original CL landed more than 1 days ago.
> > BUG=webrtc:7404
> >
> > Review-Url: https://codereview.webrtc.org/2903153005
> > Cr-Commit-Position: refs/heads/master@{#18270}
> > Committed: https://chromium.googlesource.com/external/webrtc/+/d2303a2338106feab684860f1c133877b46bdd4f
>
> TBR=solenberg@webrtc.org,tommi@webrtc.org,perkj@webrtc.org,danilchap@webrtc.org,tommi@chromium.org
> # Skipping CQ checks because original CL landed less than 1 days ago.
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:7404
>
> Review-Url: https://codereview.webrtc.org/2910633002
> Cr-Commit-Position: refs/heads/master@{#18272}
> Committed: https://chromium.googlesource.com/external/webrtc/+/fe9ecb07ea8254d8a09605f25203a4d045b3ffee
TBR=solenberg@webrtc.org,tommi@webrtc.org,perkj@webrtc.org,danilchap@webrtc.org,tommi@chromium.org
# Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=webrtc:7404
Review-Url: https://codereview.webrtc.org/2904423002
Cr-Commit-Position: refs/heads/master@{#18300}
2017-05-29 02:56:27 -07:00
apm ( ) - > DetachAecDump ( ) ;
2013-07-10 00:45:36 +00:00
}
2015-10-20 15:49:38 -07:00
int WebRtcVoiceEngine : : CreateVoEChannel ( ) {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2016-09-07 07:34:41 -07:00
return voe_wrapper_ - > base ( ) - > CreateChannel ( channel_config_ ) ;
2013-12-05 00:24:06 +00:00
}
2016-04-08 05:35:48 -07:00
webrtc : : AudioDeviceModule * WebRtcVoiceEngine : : adm ( ) {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
RTC_DCHECK ( adm_ ) ;
return adm_ ;
}
2017-07-25 15:45:24 -07:00
webrtc : : AudioProcessing * WebRtcVoiceEngine : : apm ( ) const {
2016-10-26 05:12:24 -07:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2017-06-29 08:32:09 -07:00
return apm_ . get ( ) ;
2016-10-26 05:12:24 -07:00
}
2017-02-21 00:54:31 -08:00
webrtc : : voe : : TransmitMixer * WebRtcVoiceEngine : : transmit_mixer ( ) {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
RTC_DCHECK ( transmit_mixer_ ) ;
return transmit_mixer_ ;
}
2017-04-27 02:08:52 -07:00
AudioCodecs WebRtcVoiceEngine : : CollectCodecs (
const std : : vector < webrtc : : AudioCodecSpec > & specs ) const {
2016-08-17 02:45:41 -07:00
PayloadTypeMapper mapper ;
AudioCodecs out ;
2016-11-17 04:45:19 -08:00
// Only generate CN payload types for these clockrates:
2016-08-17 02:45:41 -07:00
std : : map < int , bool , std : : greater < int > > generate_cn = { { 8000 , false } ,
{ 16000 , false } ,
{ 32000 , false } } ;
2016-11-17 04:45:19 -08:00
// Only generate telephone-event payload types for these clockrates:
std : : map < int , bool , std : : greater < int > > generate_dtmf = { { 8000 , false } ,
{ 16000 , false } ,
{ 32000 , false } ,
{ 48000 , false } } ;
2016-08-17 02:45:41 -07:00
2017-02-09 05:14:32 -08:00
auto map_format = [ & mapper ] ( const webrtc : : SdpAudioFormat & format ,
AudioCodecs * out ) {
2016-08-17 02:45:41 -07:00
rtc : : Optional < AudioCodec > opt_codec = mapper . ToAudioCodec ( format ) ;
2017-02-09 05:14:32 -08:00
if ( opt_codec ) {
if ( out ) {
out - > push_back ( * opt_codec ) ;
}
} else {
2016-08-17 02:45:41 -07:00
LOG ( LS_ERROR ) < < " Unable to assign payload type to format: " < < format ;
}
2017-02-09 05:14:32 -08:00
return opt_codec ;
2016-08-17 02:45:41 -07:00
} ;
2016-08-18 02:01:17 -07:00
for ( const auto & spec : specs ) {
2017-02-09 05:14:32 -08:00
// We need to do some extra stuff before adding the main codecs to out.
rtc : : Optional < AudioCodec > opt_codec = map_format ( spec . format , nullptr ) ;
if ( opt_codec ) {
AudioCodec & codec = * opt_codec ;
2017-04-06 10:03:21 -07:00
if ( spec . info . supports_network_adaption ) {
2017-02-09 05:14:32 -08:00
codec . AddFeedbackParam (
FeedbackParam ( kRtcpFbParamTransportCc , kParamValueEmpty ) ) ;
}
2017-04-06 10:03:21 -07:00
if ( spec . info . allow_comfort_noise ) {
2016-11-17 04:45:19 -08:00
// Generate a CN entry if the decoder allows it and we support the
// clockrate.
auto cn = generate_cn . find ( spec . format . clockrate_hz ) ;
if ( cn ! = generate_cn . end ( ) ) {
cn - > second = true ;
}
}
// Generate a telephone-event entry if we support the clockrate.
auto dtmf = generate_dtmf . find ( spec . format . clockrate_hz ) ;
if ( dtmf ! = generate_dtmf . end ( ) ) {
dtmf - > second = true ;
2016-08-17 02:45:41 -07:00
}
2017-02-09 05:14:32 -08:00
out . push_back ( codec ) ;
2016-08-17 02:45:41 -07:00
}
}
2016-11-17 04:45:19 -08:00
// Add CN codecs after "proper" audio codecs.
2016-08-17 02:45:41 -07:00
for ( const auto & cn : generate_cn ) {
if ( cn . second ) {
2017-02-09 05:14:32 -08:00
map_format ( { kCnCodecName , cn . first , 1 } , & out ) ;
2016-08-17 02:45:41 -07:00
}
}
2016-11-17 04:45:19 -08:00
// Add telephone-event codecs last.
for ( const auto & dtmf : generate_dtmf ) {
if ( dtmf . second ) {
2017-02-09 05:14:32 -08:00
map_format ( { kDtmfCodecName , dtmf . first , 1 } , & out ) ;
2016-11-17 04:45:19 -08:00
}
}
2016-08-17 02:45:41 -07:00
return out ;
}
2015-10-21 13:01:53 -07:00
class WebRtcVoiceMediaChannel : : WebRtcAudioSendStream
2016-03-08 12:37:39 -08:00
: public AudioSource : : Sink {
2014-02-03 16:57:16 +00:00
public :
2016-10-20 03:27:12 -07:00
WebRtcAudioSendStream (
int ch ,
webrtc : : AudioTransport * voe_audio_transport ,
uint32_t ssrc ,
const std : : string & c_name ,
2017-04-27 02:08:52 -07:00
const rtc : : Optional < webrtc : : AudioSendStream : : Config : : SendCodecSpec > &
send_codec_spec ,
2016-10-20 03:27:12 -07:00
const std : : vector < webrtc : : RtpExtension > & extensions ,
int max_send_bitrate_bps ,
2016-10-31 04:08:32 -07:00
const rtc : : Optional < std : : string > & audio_network_adaptor_config ,
2016-10-20 03:27:12 -07:00
webrtc : : Call * call ,
2017-04-27 02:08:52 -07:00
webrtc : : Transport * send_transport ,
const rtc : : scoped_refptr < webrtc : : AudioEncoderFactory > & encoder_factory )
2015-11-20 09:59:34 -08:00
: voe_audio_transport_ ( voe_audio_transport ) ,
2015-11-16 07:34:50 -08:00
call_ ( call ) ,
2016-04-29 00:57:13 -07:00
config_ ( send_transport ) ,
2017-02-28 08:50:47 -08:00
send_side_bwe_with_overhead_ (
webrtc : : field_trial : : IsEnabled ( " WebRTC-SendSideBwe-WithOverhead " ) ) ,
2016-10-20 03:27:12 -07:00
max_send_bitrate_bps_ ( max_send_bitrate_bps ) ,
2016-04-07 22:59:22 -07:00
rtp_parameters_ ( CreateRtpParametersWithOneEncoding ( ) ) {
2015-10-27 03:35:21 -07:00
RTC_DCHECK_GE ( ch , 0 ) ;
// TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore:
// RTC_DCHECK(voe_audio_transport);
2015-10-21 13:01:53 -07:00
RTC_DCHECK ( call ) ;
2017-04-27 02:08:52 -07:00
RTC_DCHECK ( encoder_factory ) ;
2015-11-16 07:34:50 -08:00
config_ . rtp . ssrc = ssrc ;
config_ . rtp . c_name = c_name ;
config_ . voe_channel_id = ch ;
2016-06-14 10:02:41 -07:00
config_ . rtp . extensions = extensions ;
2016-10-31 04:08:32 -07:00
config_ . audio_network_adaptor_config = audio_network_adaptor_config ;
2017-04-27 02:08:52 -07:00
config_ . encoder_factory = encoder_factory ;
2016-12-12 11:12:36 -08:00
rtp_parameters_ . encodings [ 0 ] . ssrc = rtc : : Optional < uint32_t > ( ssrc ) ;
2017-04-27 02:08:52 -07:00
if ( send_codec_spec ) {
UpdateSendCodecSpec ( * send_codec_spec ) ;
}
stream_ = call_ - > CreateAudioSendStream ( config_ ) ;
2015-10-21 13:01:53 -07:00
}
2015-11-16 07:34:50 -08:00
2015-10-21 13:01:53 -07:00
~ WebRtcAudioSendStream ( ) override {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2016-03-08 12:37:39 -08:00
ClearSource ( ) ;
2015-10-21 13:01:53 -07:00
call_ - > DestroyAudioSendStream ( stream_ ) ;
}
2014-02-03 16:57:16 +00:00
2017-04-27 02:08:52 -07:00
void SetSendCodecSpec (
2016-10-20 03:27:12 -07:00
const webrtc : : AudioSendStream : : Config : : SendCodecSpec & send_codec_spec ) {
2017-04-27 02:08:52 -07:00
UpdateSendCodecSpec ( send_codec_spec ) ;
ReconfigureAudioSendStream ( ) ;
2016-06-14 10:02:41 -07:00
}
2017-04-27 02:08:52 -07:00
void SetRtpExtensions ( const std : : vector < webrtc : : RtpExtension > & extensions ) {
2015-11-16 07:34:50 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
config_ . rtp . extensions = extensions ;
2017-04-27 02:08:52 -07:00
ReconfigureAudioSendStream ( ) ;
2015-11-16 07:34:50 -08:00
}
2017-04-27 02:08:52 -07:00
void SetAudioNetworkAdaptorConfig (
2016-10-31 04:08:32 -07:00
const rtc : : Optional < std : : string > & audio_network_adaptor_config ) {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
if ( config_ . audio_network_adaptor_config = = audio_network_adaptor_config ) {
return ;
}
config_ . audio_network_adaptor_config = audio_network_adaptor_config ;
2017-04-27 02:08:52 -07:00
UpdateAllowedBitrateRange ( ) ;
ReconfigureAudioSendStream ( ) ;
2016-10-31 04:08:32 -07:00
}
2016-10-20 03:27:12 -07:00
bool SetMaxSendBitrate ( int bps ) {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2017-04-27 02:08:52 -07:00
RTC_DCHECK ( config_ . send_codec_spec ) ;
RTC_DCHECK ( audio_codec_spec_ ) ;
auto send_rate = ComputeSendBitrate (
bps , rtp_parameters_ . encodings [ 0 ] . max_bitrate_bps , * audio_codec_spec_ ) ;
2016-10-20 03:27:12 -07:00
if ( ! send_rate ) {
return false ;
}
max_send_bitrate_bps_ = bps ;
2017-04-27 02:08:52 -07:00
if ( send_rate ! = config_ . send_codec_spec - > target_bitrate_bps ) {
config_ . send_codec_spec - > target_bitrate_bps = send_rate ;
ReconfigureAudioSendStream ( ) ;
2016-10-20 03:27:12 -07:00
}
return true ;
}
2016-11-17 05:25:37 -08:00
bool SendTelephoneEvent ( int payload_type , int payload_freq , int event ,
int duration_ms ) {
2015-12-04 15:22:19 +01:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
RTC_DCHECK ( stream_ ) ;
2016-11-17 05:25:37 -08:00
return stream_ - > SendTelephoneEvent ( payload_type , payload_freq , event ,
duration_ms ) ;
2015-12-04 15:22:19 +01:00
}
2016-03-08 12:37:39 -08:00
void SetSend ( bool send ) {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
send_ = send ;
UpdateSendState ( ) ;
}
2016-06-16 10:53:22 -07:00
void SetMuted ( bool muted ) {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
RTC_DCHECK ( stream_ ) ;
stream_ - > SetMuted ( muted ) ;
muted_ = muted ;
}
bool muted ( ) const {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
return muted_ ;
}
2015-11-16 07:34:50 -08:00
webrtc : : AudioSendStream : : Stats GetStats ( ) const {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
RTC_DCHECK ( stream_ ) ;
return stream_ - > GetStats ( ) ;
}
2016-03-08 12:37:39 -08:00
// Starts the sending by setting ourselves as a sink to the AudioSource to
// get data callbacks.
2014-02-21 15:51:43 +00:00
// This method is called on the libjingle worker thread.
2014-02-03 16:57:16 +00:00
// TODO(xians): Make sure Start() is called only once.
2016-03-08 12:37:39 -08:00
void SetSource ( AudioSource * source ) {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2016-03-08 12:37:39 -08:00
RTC_DCHECK ( source ) ;
if ( source_ ) {
RTC_DCHECK ( source_ = = source ) ;
2014-02-03 16:57:16 +00:00
return ;
}
2016-03-08 12:37:39 -08:00
source - > SetSink ( this ) ;
source_ = source ;
UpdateSendState ( ) ;
2014-02-03 16:57:16 +00:00
}
2016-03-08 12:37:39 -08:00
// Stops sending by setting the sink of the AudioSource to nullptr. No data
2014-02-03 16:57:16 +00:00
// callback will be received after this method.
2014-02-21 15:51:43 +00:00
// This method is called on the libjingle worker thread.
2016-03-08 12:37:39 -08:00
void ClearSource ( ) {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2016-03-08 12:37:39 -08:00
if ( source_ ) {
source_ - > SetSink ( nullptr ) ;
source_ = nullptr ;
2015-10-09 03:27:14 -07:00
}
2016-03-08 12:37:39 -08:00
UpdateSendState ( ) ;
2014-02-03 16:57:16 +00:00
}
2016-03-08 12:37:39 -08:00
// AudioSource::Sink implementation.
2014-02-21 15:51:43 +00:00
// This method is called on the audio thread.
2015-03-04 12:58:35 +00:00
void OnData ( const void * audio_data ,
int bits_per_sample ,
int sample_rate ,
Convert channel counts to size_t.
IIRC, this was originally requested by ajm during review of the other size_t conversions I did over the past year, and I agreed it made sense, but wanted to do it separately since those changes were already gargantuan.
BUG=chromium:81439
TEST=none
R=henrik.lundin@webrtc.org, henrika@webrtc.org, kjellander@webrtc.org, minyue@webrtc.org, perkj@webrtc.org, solenberg@webrtc.org, stefan@webrtc.org, tina.legrand@webrtc.org
Review URL: https://codereview.webrtc.org/1316523002 .
Cr-Commit-Position: refs/heads/master@{#11229}
2016-01-12 16:26:35 -08:00
size_t number_of_channels ,
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
size_t number_of_frames ) override {
2016-09-23 04:21:47 -07:00
RTC_CHECK_RUNS_SERIALIZED ( & audio_capture_race_checker_ ) ;
2015-10-21 13:01:53 -07:00
RTC_DCHECK ( voe_audio_transport_ ) ;
2016-08-15 11:46:19 -07:00
voe_audio_transport_ - > PushCaptureData ( config_ . voe_channel_id , audio_data ,
bits_per_sample , sample_rate ,
number_of_channels , number_of_frames ) ;
2014-02-21 15:51:43 +00:00
}
2016-03-08 12:37:39 -08:00
// Callback from the |source_| when it is going away. In case Start() has
2014-02-21 15:51:43 +00:00
// never been called, this callback won't be triggered.
2015-03-04 12:58:35 +00:00
void OnClose ( ) override {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2016-03-08 12:37:39 -08:00
// Set |source_| to nullptr to make sure no more callback will get into
// the source.
source_ = nullptr ;
UpdateSendState ( ) ;
2014-02-03 16:57:16 +00:00
}
// Accessor to the VoE channel ID.
2015-10-27 03:35:21 -07:00
int channel ( ) const {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2015-11-20 09:59:34 -08:00
return config_ . voe_channel_id ;
2015-10-27 03:35:21 -07:00
}
2014-02-03 16:57:16 +00:00
2016-04-07 22:59:22 -07:00
const webrtc : : RtpParameters & rtp_parameters ( ) const {
return rtp_parameters_ ;
}
2017-01-06 23:05:37 -08:00
bool ValidateRtpParameters ( const webrtc : : RtpParameters & rtp_parameters ) {
if ( rtp_parameters . encodings . size ( ) ! = 1 ) {
LOG ( LS_ERROR )
< < " Attempted to set RtpParameters without exactly one encoding " ;
return false ;
}
if ( rtp_parameters . encodings [ 0 ] . ssrc ! = rtp_parameters_ . encodings [ 0 ] . ssrc ) {
LOG ( LS_ERROR ) < < " Attempted to set RtpParameters with modified SSRC " ;
return false ;
}
return true ;
}
2016-10-20 03:27:12 -07:00
bool SetRtpParameters ( const webrtc : : RtpParameters & parameters ) {
2017-01-06 23:05:37 -08:00
if ( ! ValidateRtpParameters ( parameters ) ) {
return false ;
}
2017-04-27 02:08:52 -07:00
rtc : : Optional < int > send_rate ;
if ( audio_codec_spec_ ) {
send_rate = ComputeSendBitrate ( max_send_bitrate_bps_ ,
parameters . encodings [ 0 ] . max_bitrate_bps ,
* audio_codec_spec_ ) ;
if ( ! send_rate ) {
return false ;
}
2016-10-20 03:27:12 -07:00
}
2017-03-27 13:04:25 -07:00
const rtc : : Optional < int > old_rtp_max_bitrate =
rtp_parameters_ . encodings [ 0 ] . max_bitrate_bps ;
2016-04-07 22:59:22 -07:00
rtp_parameters_ = parameters ;
2016-10-20 03:27:12 -07:00
2017-03-27 13:04:25 -07:00
if ( rtp_parameters_ . encodings [ 0 ] . max_bitrate_bps ! = old_rtp_max_bitrate ) {
2017-04-27 02:08:52 -07:00
// Reconfigure AudioSendStream with new bit rate.
if ( send_rate ) {
config_ . send_codec_spec - > target_bitrate_bps = send_rate ;
}
UpdateAllowedBitrateRange ( ) ;
ReconfigureAudioSendStream ( ) ;
2016-10-20 03:27:12 -07:00
} else {
// parameters.encodings[0].active could have changed.
UpdateSendState ( ) ;
}
return true ;
2016-04-07 22:59:22 -07:00
}
2014-02-03 16:57:16 +00:00
private :
2016-03-08 12:37:39 -08:00
void UpdateSendState ( ) {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
RTC_DCHECK ( stream_ ) ;
2016-05-03 13:50:11 -07:00
RTC_DCHECK_EQ ( 1UL , rtp_parameters_ . encodings . size ( ) ) ;
if ( send_ & & source_ ! = nullptr & & rtp_parameters_ . encodings [ 0 ] . active ) {
2016-03-08 12:37:39 -08:00
stream_ - > Start ( ) ;
} else { // !send || source_ = nullptr
stream_ - > Stop ( ) ;
}
}
2017-04-27 02:08:52 -07:00
void UpdateAllowedBitrateRange ( ) {
2016-10-18 09:39:22 -07:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2017-04-27 02:08:52 -07:00
const bool is_opus =
config_ . send_codec_spec & &
! STR_CASE_CMP ( config_ . send_codec_spec - > format . name . c_str ( ) ,
kOpusCodecName ) ;
if ( is_opus & & webrtc : : field_trial : : IsEnabled ( " WebRTC-Audio-SendSideBwe " ) ) {
2017-01-24 08:18:45 -08:00
config_ . min_bitrate_bps = kOpusMinBitrateBps ;
2017-03-27 13:04:25 -07:00
// This means that when RtpParameters is reset, we may change the
2017-04-27 02:08:52 -07:00
// encoder's bit rate immediately (through ReconfigureAudioSendStream()),
2017-03-27 13:04:25 -07:00
// meanwhile change the cap to the output of BWE.
config_ . max_bitrate_bps =
rtp_parameters_ . encodings [ 0 ] . max_bitrate_bps
? * rtp_parameters_ . encodings [ 0 ] . max_bitrate_bps
: kOpusBitrateFbBps ;
2016-10-18 09:39:22 -07:00
// TODO(mflodman): Keep testing this and set proper values.
// Note: This is an early experiment currently only supported by Opus.
2017-01-31 05:48:37 -08:00
if ( send_side_bwe_with_overhead_ ) {
2017-04-27 02:08:52 -07:00
const int max_packet_size_ms =
WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60 ;
// OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12 ;
int min_overhead_bps =
kOverheadPerPacket * 8 * 1000 / max_packet_size_ms ;
// We assume that |config_.max_bitrate_bps| before the next line is
// a hard limit on the payload bitrate, so we add min_overhead_bps to
// it to ensure that, when overhead is deducted, the payload rate
// never goes beyond the limit.
// Note: this also means that if a higher overhead is forced, we
// cannot reach the limit.
// TODO(minyue): Reconsider this when the signaling to BWE is done
// through a dedicated API.
config_ . max_bitrate_bps + = min_overhead_bps ;
// In contrast to max_bitrate_bps, we let min_bitrate_bps always be
// reachable.
config_ . min_bitrate_bps + = min_overhead_bps ;
2017-01-11 10:17:59 -08:00
}
2016-10-18 09:39:22 -07:00
}
2017-04-27 02:08:52 -07:00
}
void UpdateSendCodecSpec (
const webrtc : : AudioSendStream : : Config : : SendCodecSpec & send_codec_spec ) {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
config_ . rtp . nack . rtp_history_ms =
send_codec_spec . nack_enabled ? kNackRtpHistoryMs : 0 ;
config_ . send_codec_spec =
rtc : : Optional < webrtc : : AudioSendStream : : Config : : SendCodecSpec > (
send_codec_spec ) ;
auto info =
config_ . encoder_factory - > QueryAudioEncoder ( send_codec_spec . format ) ;
RTC_DCHECK ( info ) ;
// If a specific target bitrate has been set for the stream, use that as
// the new default bitrate when computing send bitrate.
if ( send_codec_spec . target_bitrate_bps ) {
info - > default_bitrate_bps = std : : max (
info - > min_bitrate_bps ,
std : : min ( info - > max_bitrate_bps , * send_codec_spec . target_bitrate_bps ) ) ;
}
audio_codec_spec_ . emplace (
webrtc : : AudioCodecSpec { send_codec_spec . format , * info } ) ;
config_ . send_codec_spec - > target_bitrate_bps = ComputeSendBitrate (
max_send_bitrate_bps_ , rtp_parameters_ . encodings [ 0 ] . max_bitrate_bps ,
* audio_codec_spec_ ) ;
UpdateAllowedBitrateRange ( ) ;
}
void ReconfigureAudioSendStream ( ) {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
RTC_DCHECK ( stream_ ) ;
stream_ - > Reconfigure ( config_ ) ;
2016-10-18 09:39:22 -07:00
}
2015-11-06 15:34:49 -08:00
rtc : : ThreadChecker worker_thread_checker_ ;
2016-09-23 04:21:47 -07:00
rtc : : RaceChecker audio_capture_race_checker_ ;
2015-10-21 13:01:53 -07:00
webrtc : : AudioTransport * const voe_audio_transport_ = nullptr ;
webrtc : : Call * call_ = nullptr ;
2015-11-16 07:34:50 -08:00
webrtc : : AudioSendStream : : Config config_ ;
2017-01-31 05:48:37 -08:00
const bool send_side_bwe_with_overhead_ ;
2015-11-16 07:34:50 -08:00
// The stream is owned by WebRtcAudioSendStream and may be reallocated if
// configuration changes.
2015-10-21 13:01:53 -07:00
webrtc : : AudioSendStream * stream_ = nullptr ;
2014-02-03 16:57:16 +00:00
2016-03-08 12:37:39 -08:00
// Raw pointer to AudioSource owned by LocalAudioTrackHandler.
2014-02-03 16:57:16 +00:00
// PeerConnection will make sure invalidating the pointer before the object
// goes away.
2016-03-08 12:37:39 -08:00
AudioSource * source_ = nullptr ;
bool send_ = false ;
2016-06-16 10:53:22 -07:00
bool muted_ = false ;
2016-10-20 03:27:12 -07:00
int max_send_bitrate_bps_ ;
2016-04-07 22:59:22 -07:00
webrtc : : RtpParameters rtp_parameters_ ;
2017-04-27 02:08:52 -07:00
rtc : : Optional < webrtc : : AudioCodecSpec > audio_codec_spec_ ;
2014-02-21 15:51:43 +00:00
2015-10-21 13:01:53 -07:00
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS ( WebRtcAudioSendStream ) ;
} ;
class WebRtcVoiceMediaChannel : : WebRtcAudioReceiveStream {
public :
2016-06-13 07:34:51 -07:00
WebRtcAudioReceiveStream (
int ch ,
uint32_t remote_ssrc ,
uint32_t local_ssrc ,
bool use_transport_cc ,
2016-06-14 12:13:00 -07:00
bool use_nack ,
2016-06-13 07:34:51 -07:00
const std : : string & sync_group ,
const std : : vector < webrtc : : RtpExtension > & extensions ,
webrtc : : Call * call ,
webrtc : : Transport * rtcp_send_transport ,
2017-03-27 07:15:49 -07:00
const rtc : : scoped_refptr < webrtc : : AudioDecoderFactory > & decoder_factory ,
const std : : map < int , webrtc : : SdpAudioFormat > & decoder_map )
2016-02-04 04:12:24 -08:00
: call_ ( call ) , config_ ( ) {
2015-11-20 09:59:34 -08:00
RTC_DCHECK_GE ( ch , 0 ) ;
RTC_DCHECK ( call ) ;
config_ . rtp . remote_ssrc = remote_ssrc ;
2017-01-19 07:03:59 -08:00
config_ . rtp . local_ssrc = local_ssrc ;
config_ . rtp . transport_cc = use_transport_cc ;
config_ . rtp . nack . rtp_history_ms = use_nack ? kNackRtpHistoryMs : 0 ;
config_ . rtp . extensions = extensions ;
2016-05-06 02:13:12 -07:00
config_ . rtcp_send_transport = rtcp_send_transport ;
2015-11-20 09:59:34 -08:00
config_ . voe_channel_id = ch ;
config_ . sync_group = sync_group ;
2016-06-13 07:34:51 -07:00
config_ . decoder_factory = decoder_factory ;
2017-03-27 07:15:49 -07:00
config_ . decoder_map = decoder_map ;
2017-01-19 07:03:59 -08:00
RecreateAudioReceiveStream ( ) ;
2015-11-20 09:59:34 -08:00
}
2015-10-21 13:01:53 -07:00
2015-11-20 09:59:34 -08:00
~ WebRtcAudioReceiveStream ( ) {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
call_ - > DestroyAudioReceiveStream ( stream_ ) ;
}
2016-06-16 13:07:33 -07:00
void RecreateAudioReceiveStream ( uint32_t local_ssrc ) {
2015-11-20 09:59:34 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2017-01-19 07:03:59 -08:00
config_ . rtp . local_ssrc = local_ssrc ;
RecreateAudioReceiveStream ( ) ;
2015-11-20 09:59:34 -08:00
}
2016-06-14 12:13:00 -07:00
void RecreateAudioReceiveStream ( bool use_transport_cc , bool use_nack ) {
2015-11-20 09:59:34 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2017-01-19 07:03:59 -08:00
config_ . rtp . transport_cc = use_transport_cc ;
config_ . rtp . nack . rtp_history_ms = use_nack ? kNackRtpHistoryMs : 0 ;
RecreateAudioReceiveStream ( ) ;
2015-11-20 09:59:34 -08:00
}
2016-06-16 13:07:33 -07:00
void RecreateAudioReceiveStream (
const std : : vector < webrtc : : RtpExtension > & extensions ) {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2017-01-19 07:03:59 -08:00
config_ . rtp . extensions = extensions ;
RecreateAudioReceiveStream ( ) ;
}
2017-04-26 16:28:42 -07:00
// Set a new payload type -> decoder map.
2017-01-19 07:03:59 -08:00
void RecreateAudioReceiveStream (
const std : : map < int , webrtc : : SdpAudioFormat > & decoder_map ) {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
config_ . decoder_map = decoder_map ;
RecreateAudioReceiveStream ( ) ;
2016-06-16 13:07:33 -07:00
}
2017-02-17 12:01:14 -08:00
void MaybeRecreateAudioReceiveStream ( const std : : string & sync_group ) {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
if ( config_ . sync_group ! = sync_group ) {
config_ . sync_group = sync_group ;
RecreateAudioReceiveStream ( ) ;
}
}
2015-11-20 09:59:34 -08:00
webrtc : : AudioReceiveStream : : Stats GetStats ( ) const {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
RTC_DCHECK ( stream_ ) ;
return stream_ - > GetStats ( ) ;
}
2017-03-01 17:02:23 -08:00
int GetOutputLevel ( ) const {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
RTC_DCHECK ( stream_ ) ;
return stream_ - > GetOutputLevel ( ) ;
}
2015-11-20 09:59:34 -08:00
int channel ( ) const {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
return config_ . voe_channel_id ;
}
2015-10-21 13:01:53 -07:00
2016-02-26 03:00:35 -08:00
void SetRawAudioSink ( std : : unique_ptr < webrtc : : AudioSinkInterface > sink ) {
2015-12-12 01:37:01 +01:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2016-02-26 03:00:35 -08:00
stream_ - > SetSink ( std : : move ( sink ) ) ;
2015-12-12 01:37:01 +01:00
}
2016-06-17 08:30:54 -07:00
void SetOutputVolume ( double volume ) {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
stream_ - > SetGain ( volume ) ;
}
2016-08-04 05:28:21 -07:00
void SetPlayout ( bool playout ) {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
RTC_DCHECK ( stream_ ) ;
if ( playout ) {
LOG ( LS_INFO ) < < " Starting playout for channel # " < < channel ( ) ;
stream_ - > Start ( ) ;
} else {
LOG ( LS_INFO ) < < " Stopping playout for channel # " < < channel ( ) ;
stream_ - > Stop ( ) ;
}
2016-10-04 02:45:47 -07:00
playout_ = playout ;
2016-08-04 05:28:21 -07:00
}
Reland of Implemented the GetSources() in native code. (patchset #1 id:1 of https://codereview.webrtc.org/2809613002/ )
Reason for revert:
Re-land, reverting did not fix bug.
https://bugs.chromium.org/p/webrtc/issues/detail?id=7465
Original issue's description:
> Revert of Implemented the GetSources() in native code. (patchset #11 id:510001 of https://codereview.webrtc.org/2770233003/ )
>
> Reason for revert:
> Suspected of WebRtcApprtcBrowserTest.MANUAL_WorksOnApprtc breakage, see
>
> https://bugs.chromium.org/p/webrtc/issues/detail?id=7465
>
> Original issue's description:
> > Added the GetSources() to the RtpReceiverInterface and implemented
> > it for the AudioRtpReceiver.
> >
> > This method returns a vector of RtpSource(both CSRC source and SSRC
> > source) which contains the ID of a source, the timestamp, the source
> > type (SSRC or CSRC) and the audio level.
> >
> > The RtpSource objects are buffered and maintained by the
> > RtpReceiver in webrtc/modules/rtp_rtcp/. When the method is called,
> > the info of the contributing source will be pulled along the object
> > chain:
> > AudioRtpReceiver -> VoiceChannel -> WebRtcVoiceMediaChannel ->
> > AudioReceiveStream -> voe::Channel -> RtpRtcp module
> >
> > Spec:https://w3c.github.io/webrtc-pc/archives/20151006/webrtc.html#widl-RTCRtpReceiver-getContributingSources-sequence-RTCRtpContributingSource
> >
> > BUG=chromium:703122
> > TBR=stefan@webrtc.org, danilchap@webrtc.org
> >
> > Review-Url: https://codereview.webrtc.org/2770233003
> > Cr-Commit-Position: refs/heads/master@{#17591}
> > Committed: https://chromium.googlesource.com/external/webrtc/+/292084c3765d9f3ee406ca2ec86eae206b540053
>
> TBR=deadbeef@webrtc.org,solenberg@webrtc.org,hbos@webrtc.org,philipel@webrtc.org,stefan@webrtc.org,danilchap@webrtc.org,zhihuang@webrtc.org
> # Not skipping CQ checks because original CL landed more than 1 days ago.
> BUG=chromium:703122
>
> Review-Url: https://codereview.webrtc.org/2809613002
> Cr-Commit-Position: refs/heads/master@{#17616}
> Committed: https://chromium.googlesource.com/external/webrtc/+/fbcc5cb3869d1370008e40f24fc03ac8fb69c675
TBR=deadbeef@webrtc.org,solenberg@webrtc.org,philipel@webrtc.org,stefan@webrtc.org,danilchap@webrtc.org,zhihuang@webrtc.org,olka@webrtc.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=chromium:703122
Review-Url: https://codereview.webrtc.org/2810623003
Cr-Commit-Position: refs/heads/master@{#17621}
2017-04-10 07:39:05 -07:00
std : : vector < webrtc : : RtpSource > GetSources ( ) {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
RTC_DCHECK ( stream_ ) ;
return stream_ - > GetSources ( ) ;
}
2015-10-21 13:01:53 -07:00
private :
2017-01-19 07:03:59 -08:00
void RecreateAudioReceiveStream ( ) {
2015-11-20 09:59:34 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
if ( stream_ ) {
call_ - > DestroyAudioReceiveStream ( stream_ ) ;
}
stream_ = call_ - > CreateAudioReceiveStream ( config_ ) ;
RTC_CHECK ( stream_ ) ;
2016-10-04 02:45:47 -07:00
SetPlayout ( playout_ ) ;
2015-11-20 09:59:34 -08:00
}
rtc : : ThreadChecker worker_thread_checker_ ;
webrtc : : Call * call_ = nullptr ;
webrtc : : AudioReceiveStream : : Config config_ ;
// The stream is owned by WebRtcAudioReceiveStream and may be reallocated if
// configuration changes.
webrtc : : AudioReceiveStream * stream_ = nullptr ;
2016-10-04 02:45:47 -07:00
bool playout_ = false ;
2015-10-21 13:01:53 -07:00
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS ( WebRtcAudioReceiveStream ) ;
2013-07-26 19:17:59 +00:00
} ;
2015-09-15 12:26:33 +02:00
WebRtcVoiceMediaChannel : : WebRtcVoiceMediaChannel ( WebRtcVoiceEngine * engine ,
2016-02-12 02:27:06 -08:00
const MediaConfig & config ,
2015-09-17 16:42:56 +02:00
const AudioOptions & options ,
2015-09-15 12:26:33 +02:00
webrtc : : Call * call )
2016-02-12 02:27:06 -08:00
: VoiceMediaChannel ( config ) , engine_ ( engine ) , call_ ( call ) {
2015-10-20 15:49:38 -07:00
LOG ( LS_VERBOSE ) < < " WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel " ;
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( call ) ;
2015-10-20 15:49:38 -07:00
engine - > RegisterChannel ( this ) ;
2015-09-17 16:42:56 +02:00
SetOptions ( options ) ;
2013-07-10 00:45:36 +00:00
}
WebRtcVoiceMediaChannel : : ~ WebRtcVoiceMediaChannel ( ) {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2015-10-20 15:49:38 -07:00
LOG ( LS_VERBOSE ) < < " WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel " ;
2015-11-20 09:59:34 -08:00
// TODO(solenberg): Should be able to delete the streams directly, without
// going through RemoveNnStream(), once stream objects handle
// all (de)configuration.
2015-10-21 13:01:53 -07:00
while ( ! send_streams_ . empty ( ) ) {
RemoveSendStream ( send_streams_ . begin ( ) - > first ) ;
2015-10-07 01:40:33 -07:00
}
2015-11-20 09:59:34 -08:00
while ( ! recv_streams_ . empty ( ) ) {
RemoveRecvStream ( recv_streams_ . begin ( ) - > first ) ;
2013-07-10 00:45:36 +00:00
}
2015-10-20 15:49:38 -07:00
engine ( ) - > UnregisterChannel ( this ) ;
2013-07-10 00:45:36 +00:00
}
2016-02-12 02:27:06 -08:00
rtc : : DiffServCodePoint WebRtcVoiceMediaChannel : : PreferredDscp ( ) const {
return kAudioDscpValue ;
}
2015-08-07 16:05:34 -07:00
bool WebRtcVoiceMediaChannel : : SetSendParameters (
const AudioSendParameters & params ) {
2016-03-08 14:24:13 -08:00
TRACE_EVENT0 ( " webrtc " , " WebRtcVoiceMediaChannel::SetSendParameters " ) ;
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2015-12-02 08:05:01 -08:00
LOG ( LS_INFO ) < < " WebRtcVoiceMediaChannel::SetSendParameters: "
< < params . ToString ( ) ;
2015-08-07 16:05:34 -07:00
// TODO(pthatcher): Refactor this to be more clean now that we have
// all the information at once.
2015-11-16 07:34:50 -08:00
if ( ! SetSendCodecs ( params . codecs ) ) {
return false ;
}
2015-12-02 08:05:01 -08:00
if ( ! ValidateRtpExtensions ( params . extensions ) ) {
return false ;
}
std : : vector < webrtc : : RtpExtension > filtered_extensions =
FilterRtpExtensions ( params . extensions ,
webrtc : : RtpExtension : : IsSupportedForAudio , true ) ;
if ( send_rtp_extensions_ ! = filtered_extensions ) {
send_rtp_extensions_ . swap ( filtered_extensions ) ;
2015-11-16 07:34:50 -08:00
for ( auto & it : send_streams_ ) {
2017-04-27 02:08:52 -07:00
it . second - > SetRtpExtensions ( send_rtp_extensions_ ) ;
2015-11-16 07:34:50 -08:00
}
}
2016-04-27 14:17:10 -07:00
if ( ! SetMaxSendBitrate ( params . max_bandwidth_bps ) ) {
2015-11-16 07:34:50 -08:00
return false ;
}
return SetOptions ( params . options ) ;
2015-08-07 16:05:34 -07:00
}
bool WebRtcVoiceMediaChannel : : SetRecvParameters (
const AudioRecvParameters & params ) {
2016-03-08 14:24:13 -08:00
TRACE_EVENT0 ( " webrtc " , " WebRtcVoiceMediaChannel::SetRecvParameters " ) ;
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2015-12-02 08:05:01 -08:00
LOG ( LS_INFO ) < < " WebRtcVoiceMediaChannel::SetRecvParameters: "
< < params . ToString ( ) ;
2015-08-07 16:05:34 -07:00
// TODO(pthatcher): Refactor this to be more clean now that we have
// all the information at once.
2015-11-20 09:59:34 -08:00
if ( ! SetRecvCodecs ( params . codecs ) ) {
return false ;
}
2015-12-02 08:05:01 -08:00
if ( ! ValidateRtpExtensions ( params . extensions ) ) {
return false ;
}
std : : vector < webrtc : : RtpExtension > filtered_extensions =
FilterRtpExtensions ( params . extensions ,
webrtc : : RtpExtension : : IsSupportedForAudio , false ) ;
if ( recv_rtp_extensions_ ! = filtered_extensions ) {
recv_rtp_extensions_ . swap ( filtered_extensions ) ;
2015-11-20 09:59:34 -08:00
for ( auto & it : recv_streams_ ) {
it . second - > RecreateAudioReceiveStream ( recv_rtp_extensions_ ) ;
}
}
return true ;
2015-08-07 16:05:34 -07:00
}
2016-05-16 11:40:30 -07:00
webrtc : : RtpParameters WebRtcVoiceMediaChannel : : GetRtpSendParameters (
2016-04-07 22:59:22 -07:00
uint32_t ssrc ) const {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
auto it = send_streams_ . find ( ssrc ) ;
if ( it = = send_streams_ . end ( ) ) {
2016-05-16 11:40:30 -07:00
LOG ( LS_WARNING ) < < " Attempting to get RTP send parameters for stream "
< < " with ssrc " < < ssrc < < " which doesn't exist. " ;
2016-04-07 22:59:22 -07:00
return webrtc : : RtpParameters ( ) ;
}
2016-04-20 16:23:10 -07:00
webrtc : : RtpParameters rtp_params = it - > second - > rtp_parameters ( ) ;
// Need to add the common list of codecs to the send stream-specific
// RTP parameters.
for ( const AudioCodec & codec : send_codecs_ ) {
rtp_params . codecs . push_back ( codec . ToCodecParameters ( ) ) ;
}
return rtp_params ;
2016-04-07 22:59:22 -07:00
}
2016-05-16 11:40:30 -07:00
bool WebRtcVoiceMediaChannel : : SetRtpSendParameters (
2016-04-07 22:59:22 -07:00
uint32_t ssrc ,
const webrtc : : RtpParameters & parameters ) {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
auto it = send_streams_ . find ( ssrc ) ;
if ( it = = send_streams_ . end ( ) ) {
2016-05-16 11:40:30 -07:00
LOG ( LS_WARNING ) < < " Attempting to set RTP send parameters for stream "
< < " with ssrc " < < ssrc < < " which doesn't exist. " ;
2016-04-07 22:59:22 -07:00
return false ;
}
2016-05-16 11:40:30 -07:00
// TODO(deadbeef): Handle setting parameters with a list of codecs in a
// different order (which should change the send codec).
webrtc : : RtpParameters current_parameters = GetRtpSendParameters ( ssrc ) ;
if ( current_parameters . codecs ! = parameters . codecs ) {
LOG ( LS_ERROR ) < < " Using SetParameters to change the set of codecs "
< < " is not currently supported. " ;
return false ;
}
2016-10-20 03:27:12 -07:00
// TODO(minyue): The following legacy actions go into
// |WebRtcAudioSendStream::SetRtpParameters()| which is called at the end,
// though there are two difference:
// 1. |WebRtcVoiceMediaChannel::SetChannelSendParameters()| only calls
// |SetSendCodec| while |WebRtcAudioSendStream::SetRtpParameters()| calls
// |SetSendCodecs|. The outcome should be the same.
// 2. AudioSendStream can be recreated.
2016-04-20 16:23:10 -07:00
// Codecs are handled at the WebRtcVoiceMediaChannel level.
webrtc : : RtpParameters reduced_params = parameters ;
reduced_params . codecs . clear ( ) ;
2016-10-20 03:27:12 -07:00
return it - > second - > SetRtpParameters ( reduced_params ) ;
2016-04-07 22:59:22 -07:00
}
2016-05-16 11:40:30 -07:00
webrtc : : RtpParameters WebRtcVoiceMediaChannel : : GetRtpReceiveParameters (
uint32_t ssrc ) const {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2017-04-20 19:25:07 -07:00
webrtc : : RtpParameters rtp_params ;
// SSRC of 0 represents the default receive stream.
if ( ssrc = = 0 ) {
if ( ! default_sink_ ) {
LOG ( LS_WARNING ) < < " Attempting to get RTP parameters for the default, "
" unsignaled audio receive stream, but not yet "
" configured to receive such a stream. " ;
return rtp_params ;
}
rtp_params . encodings . emplace_back ( ) ;
} else {
auto it = recv_streams_ . find ( ssrc ) ;
if ( it = = recv_streams_ . end ( ) ) {
LOG ( LS_WARNING ) < < " Attempting to get RTP receive parameters for stream "
< < " with ssrc " < < ssrc < < " which doesn't exist. " ;
return webrtc : : RtpParameters ( ) ;
}
rtp_params . encodings . emplace_back ( ) ;
// TODO(deadbeef): Return stream-specific parameters.
rtp_params . encodings [ 0 ] . ssrc = rtc : : Optional < uint32_t > ( ssrc ) ;
2016-05-16 11:40:30 -07:00
}
for ( const AudioCodec & codec : recv_codecs_ ) {
rtp_params . codecs . push_back ( codec . ToCodecParameters ( ) ) ;
}
return rtp_params ;
}
bool WebRtcVoiceMediaChannel : : SetRtpReceiveParameters (
uint32_t ssrc ,
const webrtc : : RtpParameters & parameters ) {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2017-04-20 19:25:07 -07:00
// SSRC of 0 represents the default receive stream.
if ( ssrc = = 0 ) {
if ( ! default_sink_ ) {
LOG ( LS_WARNING ) < < " Attempting to set RTP parameters for the default, "
" unsignaled audio receive stream, but not yet "
" configured to receive such a stream. " ;
return false ;
}
} else {
auto it = recv_streams_ . find ( ssrc ) ;
if ( it = = recv_streams_ . end ( ) ) {
LOG ( LS_WARNING ) < < " Attempting to set RTP receive parameters for stream "
< < " with ssrc " < < ssrc < < " which doesn't exist. " ;
return false ;
}
2016-05-16 11:40:30 -07:00
}
webrtc : : RtpParameters current_parameters = GetRtpReceiveParameters ( ssrc ) ;
if ( current_parameters ! = parameters ) {
LOG ( LS_ERROR ) < < " Changing the RTP receive parameters is currently "
< < " unsupported. " ;
return false ;
}
return true ;
}
2013-07-10 00:45:36 +00:00
bool WebRtcVoiceMediaChannel : : SetOptions ( const AudioOptions & options ) {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2013-07-10 00:45:36 +00:00
LOG ( LS_INFO ) < < " Setting voice channel options: "
< < options . ToString ( ) ;
// We retain all of the existing options, and apply the given ones
// on top. This means there is no way to "clear" options such that
// they go back to the engine default.
options_ . SetAll ( options ) ;
2015-12-08 09:50:23 -08:00
if ( ! engine ( ) - > ApplyOptions ( options_ ) ) {
LOG ( LS_WARNING ) < <
" Failed to apply engine options during channel SetOptions. " ;
return false ;
2013-07-10 00:45:36 +00:00
}
2016-10-31 04:08:32 -07:00
2017-04-27 02:08:52 -07:00
rtc : : Optional < std : : string > audio_network_adaptor_config =
2016-10-31 04:08:32 -07:00
GetAudioNetworkAdaptorConfig ( options_ ) ;
for ( auto & it : send_streams_ ) {
2017-04-27 02:08:52 -07:00
it . second - > SetAudioNetworkAdaptorConfig ( audio_network_adaptor_config ) ;
2016-10-31 04:08:32 -07:00
}
2017-02-21 00:54:31 -08:00
LOG ( LS_INFO ) < < " Set voice channel options. Current options: "
2013-07-10 00:45:36 +00:00
< < options_ . ToString ( ) ;
return true ;
}
bool WebRtcVoiceMediaChannel : : SetRecvCodecs (
const std : : vector < AudioCodec > & codecs ) {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2015-10-13 03:06:58 -07:00
2013-07-10 00:45:36 +00:00
// Set the payload types to be used for incoming media.
2015-10-09 01:37:09 -07:00
LOG ( LS_INFO ) < < " Setting receive voice codecs. " ;
if ( ! VerifyUniquePayloadTypes ( codecs ) ) {
LOG ( LS_ERROR ) < < " Codec payload types overlap. " ;
return false ;
}
2013-07-10 00:45:36 +00:00
2017-01-19 07:03:59 -08:00
// Create a payload type -> SdpAudioFormat map with all the decoders. Fail
// unless the factory claims to support all decoders.
std : : map < int , webrtc : : SdpAudioFormat > decoder_map ;
for ( const AudioCodec & codec : codecs ) {
2017-04-26 16:28:42 -07:00
// Log a warning if a codec's payload type is changing. This used to be
// treated as an error. It's abnormal, but not really illegal.
AudioCodec old_codec ;
if ( FindCodec ( recv_codecs_ , codec , & old_codec ) & &
old_codec . id ! = codec . id ) {
LOG ( LS_WARNING ) < < codec . name < < " mapped to a second payload type ( "
< < codec . id < < " , was already mapped to " < < old_codec . id
< < " ) " ;
}
2017-01-19 07:03:59 -08:00
auto format = AudioCodecToSdpAudioFormat ( codec ) ;
if ( ! IsCodec ( codec , " cn " ) & & ! IsCodec ( codec , " telephone-event " ) & &
! engine ( ) - > decoder_factory_ - > IsSupportedDecoder ( format ) ) {
LOG ( LS_ERROR ) < < " Unsupported codec: " < < format ;
return false ;
}
2017-04-26 16:28:42 -07:00
// We allow adding new codecs but don't allow changing the payload type of
// codecs that are already configured since we might already be receiving
// packets with that payload type. See RFC3264, Section 8.3.2.
// TODO(deadbeef): Also need to check for clashes with previously mapped
// payload types, and not just currently mapped ones. For example, this
// should be illegal:
// 1. {100: opus/48000/2, 101: ISAC/16000}
// 2. {100: opus/48000/2}
// 3. {100: opus/48000/2, 101: ISAC/32000}
// Though this check really should happen at a higher level, since this
// conflict could happen between audio and video codecs.
auto existing = decoder_map_ . find ( codec . id ) ;
if ( existing ! = decoder_map_ . end ( ) & & ! existing - > second . Matches ( format ) ) {
LOG ( LS_ERROR ) < < " Attempting to use payload type " < < codec . id < < " for "
< < codec . name < < " , but it is already used for "
< < existing - > second . name ;
return false ;
}
2017-01-19 07:03:59 -08:00
decoder_map . insert ( { codec . id , std : : move ( format ) } ) ;
}
2017-04-26 16:28:42 -07:00
if ( decoder_map = = decoder_map_ ) {
// There's nothing new to configure.
return true ;
}
2016-11-03 02:46:53 -07:00
if ( playout_ ) {
// Receive codecs can not be changed while playing. So we temporarily
// pause playout.
ChangePlayout ( false ) ;
}
2017-03-27 07:15:49 -07:00
decoder_map_ = std : : move ( decoder_map ) ;
2017-01-19 07:03:59 -08:00
for ( auto & kv : recv_streams_ ) {
2017-03-27 07:15:49 -07:00
kv . second - > RecreateAudioReceiveStream ( decoder_map_ ) ;
2013-07-10 00:45:36 +00:00
}
2017-01-19 07:03:59 -08:00
recv_codecs_ = codecs ;
2013-07-10 00:45:36 +00:00
2016-11-03 02:46:53 -07:00
if ( desired_playout_ & & ! playout_ ) {
ChangePlayout ( desired_playout_ ) ;
}
2017-01-19 07:03:59 -08:00
return true ;
2013-07-10 00:45:36 +00:00
}
2016-03-08 06:35:16 -08:00
// Utility function called from SetSendParameters() to extract current send
// codec settings from the given list of codecs (originally from SDP). Both send
// and receive streams may be reconfigured based on the new settings.
2013-07-10 00:45:36 +00:00
bool WebRtcVoiceMediaChannel : : SetSendCodecs (
2016-03-08 06:35:16 -08:00
const std : : vector < AudioCodec > & codecs ) {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
dtmf_payload_type_ = rtc : : Optional < int > ( ) ;
2016-11-17 05:25:37 -08:00
dtmf_payload_freq_ = - 1 ;
// Validate supplied codecs list.
for ( const AudioCodec & codec : codecs ) {
// TODO(solenberg): Validate more aspects of input - that payload types
// don't overlap, remove redundant/unsupported codecs etc -
// the same way it is done for RtpHeaderExtensions.
if ( codec . id < kMinPayloadType | | codec . id > kMaxPayloadType ) {
LOG ( LS_WARNING ) < < " Codec payload type out of range: " < < ToString ( codec ) ;
return false ;
}
}
// Find PT of telephone-event codec with lowest clockrate, as a fallback, in
// case we don't have a DTMF codec with a rate matching the send codec's, or
// if this function returns early.
std : : vector < AudioCodec > dtmf_codecs ;
2016-03-08 06:35:16 -08:00
for ( const AudioCodec & codec : codecs ) {
if ( IsCodec ( codec , kDtmfCodecName ) ) {
2016-11-17 05:25:37 -08:00
dtmf_codecs . push_back ( codec ) ;
if ( ! dtmf_payload_type_ | | codec . clockrate < dtmf_payload_freq_ ) {
dtmf_payload_type_ = rtc : : Optional < int > ( codec . id ) ;
dtmf_payload_freq_ = codec . clockrate ;
2016-03-14 08:00:37 -07:00
}
2016-03-08 06:35:16 -08:00
}
}
2013-07-10 00:45:36 +00:00
2017-04-27 02:08:52 -07:00
// Scan through the list to figure out the codec to use for sending.
rtc : : Optional < webrtc : : AudioSendStream : : Config : : SendCodecSpec > send_codec_spec ;
2017-03-27 03:51:18 -07:00
webrtc : : Call : : Config : : BitrateConfig bitrate_config ;
2017-04-27 02:08:52 -07:00
rtc : : Optional < webrtc : : AudioCodecInfo > voice_codec_info ;
for ( const AudioCodec & voice_codec : codecs ) {
if ( ! ( IsCodec ( voice_codec , kCnCodecName ) | |
IsCodec ( voice_codec , kDtmfCodecName ) | |
IsCodec ( voice_codec , kRedCodecName ) ) ) {
webrtc : : SdpAudioFormat format ( voice_codec . name , voice_codec . clockrate ,
voice_codec . channels , voice_codec . params ) ;
voice_codec_info = engine ( ) - > encoder_factory_ - > QueryAudioEncoder ( format ) ;
if ( ! voice_codec_info ) {
LOG ( LS_WARNING ) < < " Unknown codec " < < ToString ( voice_codec ) ;
continue ;
}
2016-03-08 06:35:16 -08:00
2017-04-27 02:08:52 -07:00
send_codec_spec =
rtc : : Optional < webrtc : : AudioSendStream : : Config : : SendCodecSpec > (
{ voice_codec . id , format } ) ;
if ( voice_codec . bitrate > 0 ) {
send_codec_spec - > target_bitrate_bps =
rtc : : Optional < int > ( voice_codec . bitrate ) ;
2015-03-26 07:39:19 +08:00
}
2017-04-27 02:08:52 -07:00
send_codec_spec - > transport_cc_enabled = HasTransportCc ( voice_codec ) ;
send_codec_spec - > nack_enabled = HasNack ( voice_codec ) ;
bitrate_config = GetBitrateConfigForCodec ( voice_codec ) ;
break ;
2014-02-27 17:52:04 +00:00
}
2017-04-27 02:08:52 -07:00
}
if ( ! send_codec_spec ) {
return false ;
}
2016-03-08 06:35:16 -08:00
2017-04-27 02:08:52 -07:00
RTC_DCHECK ( voice_codec_info ) ;
if ( voice_codec_info - > allow_comfort_noise ) {
2016-03-08 06:35:16 -08:00
// Loop through the codecs list again to find the CN codec.
// TODO(solenberg): Break out into a separate function?
2017-03-02 11:03:25 -08:00
for ( const AudioCodec & cn_codec : codecs ) {
if ( IsCodec ( cn_codec , kCnCodecName ) & &
2017-04-27 02:08:52 -07:00
cn_codec . clockrate = = send_codec_spec - > format . clockrate_hz ) {
2017-03-02 11:03:25 -08:00
switch ( cn_codec . clockrate ) {
2016-03-08 06:35:16 -08:00
case 8000 :
case 16000 :
case 32000 :
2017-04-27 02:08:52 -07:00
send_codec_spec - > cng_payload_type = rtc : : Optional < int > ( cn_codec . id ) ;
2016-03-08 06:35:16 -08:00
break ;
default :
2017-03-02 11:03:25 -08:00
LOG ( LS_WARNING ) < < " CN frequency " < < cn_codec . clockrate
2016-03-08 06:35:16 -08:00
< < " not supported. " ;
2017-04-27 02:08:52 -07:00
break ;
2016-03-08 06:35:16 -08:00
}
break ;
}
}
2016-11-17 05:25:37 -08:00
// Find the telephone-event PT exactly matching the preferred send codec.
for ( const AudioCodec & dtmf_codec : dtmf_codecs ) {
2017-04-27 02:08:52 -07:00
if ( dtmf_codec . clockrate = = send_codec_spec - > format . clockrate_hz ) {
2016-11-17 05:25:37 -08:00
dtmf_payload_type_ = rtc : : Optional < int > ( dtmf_codec . id ) ;
dtmf_payload_freq_ = dtmf_codec . clockrate ;
break ;
}
}
2016-03-08 06:35:16 -08:00
}
2016-06-14 10:02:41 -07:00
if ( send_codec_spec_ ! = send_codec_spec ) {
send_codec_spec_ = std : : move ( send_codec_spec ) ;
2016-11-30 07:22:58 -08:00
// Apply new settings to all streams.
2016-06-14 10:02:41 -07:00
for ( const auto & kv : send_streams_ ) {
2017-04-27 02:08:52 -07:00
kv . second - > SetSendCodecSpec ( * send_codec_spec_ ) ;
2016-03-08 06:35:16 -08:00
}
2016-11-30 07:22:58 -08:00
} else {
// If the codec isn't changing, set the start bitrate to -1 which means
// "unchanged" so that BWE isn't affected.
2017-03-27 03:51:18 -07:00
bitrate_config . start_bitrate_bps = - 1 ;
2014-02-27 17:52:04 +00:00
}
2017-03-27 03:51:18 -07:00
call_ - > SetBitrateConfig ( bitrate_config ) ;
2014-02-27 17:52:04 +00:00
2016-06-14 12:13:00 -07:00
// Check if the transport cc feedback or NACK status has changed on the
// preferred send codec, and in that case reconfigure all receive streams.
2017-04-27 02:08:52 -07:00
if ( recv_transport_cc_enabled_ ! = send_codec_spec_ - > transport_cc_enabled | |
recv_nack_enabled_ ! = send_codec_spec_ - > nack_enabled ) {
2016-03-08 06:35:16 -08:00
LOG ( LS_INFO ) < < " Recreate all the receive streams because the send "
" codec has changed. " ;
2017-04-27 02:08:52 -07:00
recv_transport_cc_enabled_ = send_codec_spec_ - > transport_cc_enabled ;
recv_nack_enabled_ = send_codec_spec_ - > nack_enabled ;
2016-03-08 06:35:16 -08:00
for ( auto & kv : recv_streams_ ) {
2016-06-14 12:13:00 -07:00
kv . second - > RecreateAudioReceiveStream ( recv_transport_cc_enabled_ ,
recv_nack_enabled_ ) ;
2016-03-08 06:35:16 -08:00
}
2014-02-27 17:52:04 +00:00
}
2016-04-20 16:23:10 -07:00
send_codecs_ = codecs ;
2016-03-08 06:35:16 -08:00
return true ;
}
2016-08-04 05:28:21 -07:00
void WebRtcVoiceMediaChannel : : SetPlayout ( bool playout ) {
2016-11-03 02:46:53 -07:00
desired_playout_ = playout ;
return ChangePlayout ( desired_playout_ ) ;
}
void WebRtcVoiceMediaChannel : : ChangePlayout ( bool playout ) {
TRACE_EVENT0 ( " webrtc " , " WebRtcVoiceMediaChannel::ChangePlayout " ) ;
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2013-07-10 00:45:36 +00:00
if ( playout_ = = playout ) {
2016-08-04 05:28:21 -07:00
return ;
2013-07-10 00:45:36 +00:00
}
2016-08-04 05:28:21 -07:00
for ( const auto & kv : recv_streams_ ) {
kv . second - > SetPlayout ( playout ) ;
2013-07-10 00:45:36 +00:00
}
2015-10-13 03:58:19 -07:00
playout_ = playout ;
2013-07-10 00:45:36 +00:00
}
2016-03-08 12:37:39 -08:00
void WebRtcVoiceMediaChannel : : SetSend ( bool send ) {
2016-03-08 14:24:13 -08:00
TRACE_EVENT0 ( " webrtc " , " WebRtcVoiceMediaChannel::SetSend " ) ;
2013-07-10 00:45:36 +00:00
if ( send_ = = send ) {
2016-03-08 12:37:39 -08:00
return ;
2013-07-10 00:45:36 +00:00
}
2016-04-14 13:56:37 -07:00
// Apply channel specific options, and initialize the ADM for recording (this
// may take time on some platforms, e.g. Android).
2016-03-08 12:37:39 -08:00
if ( send ) {
2015-09-29 06:06:31 -07:00
engine ( ) - > ApplyOptions ( options_ ) ;
2016-04-14 13:56:37 -07:00
// InitRecording() may return an error if the ADM is already recording.
if ( ! engine ( ) - > adm ( ) - > RecordingIsInitialized ( ) & &
! engine ( ) - > adm ( ) - > Recording ( ) ) {
if ( engine ( ) - > adm ( ) - > InitRecording ( ) ! = 0 ) {
LOG ( LS_WARNING ) < < " Failed to initialize recording " ;
}
}
2015-09-29 06:06:31 -07:00
}
2013-07-10 00:45:36 +00:00
2013-08-05 20:36:57 +00:00
// Change the settings on each send channel.
2016-03-08 12:37:39 -08:00
for ( auto & kv : send_streams_ ) {
kv . second - > SetSend ( send ) ;
2013-08-05 20:36:57 +00:00
}
send_ = send ;
2015-09-10 01:57:14 -07:00
}
Use suffixed {uint,int}{8,16,32,64}_t types.
Removes the use of uint8, etc. in favor of uint8_t.
BUG=webrtc:5024
R=henrik.lundin@webrtc.org, henrikg@webrtc.org, perkj@webrtc.org, solenberg@webrtc.org, stefan@webrtc.org, tina.legrand@webrtc.org
Review URL: https://codereview.webrtc.org/1362503003 .
Cr-Commit-Position: refs/heads/master@{#10196}
2015-10-07 12:23:21 +02:00
bool WebRtcVoiceMediaChannel : : SetAudioSend ( uint32_t ssrc ,
bool enable ,
2015-09-10 01:57:14 -07:00
const AudioOptions * options ,
2016-03-08 12:37:39 -08:00
AudioSource * source ) {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2015-09-10 01:57:14 -07:00
// TODO(solenberg): The state change should be fully rolled back if any one of
// these calls fail.
2016-03-08 12:37:39 -08:00
if ( ! SetLocalSource ( ssrc , source ) ) {
2015-09-10 01:57:14 -07:00
return false ;
}
2015-10-01 02:31:10 -07:00
if ( ! MuteStream ( ssrc , ! enable ) ) {
2015-09-10 01:57:14 -07:00
return false ;
}
2015-10-01 02:31:10 -07:00
if ( enable & & options ) {
2015-09-10 01:57:14 -07:00
return SetOptions ( * options ) ;
}
return true ;
2013-08-05 20:36:57 +00:00
}
2015-10-20 15:49:38 -07:00
int WebRtcVoiceMediaChannel : : CreateVoEChannel ( ) {
int id = engine ( ) - > CreateVoEChannel ( ) ;
if ( id = = - 1 ) {
LOG_RTCERR0 ( CreateVoEChannel ) ;
return - 1 ;
2013-07-10 00:45:36 +00:00
}
2016-04-29 00:57:13 -07:00
2015-10-20 15:49:38 -07:00
return id ;
2013-08-05 20:36:57 +00:00
}
2015-11-20 09:59:34 -08:00
bool WebRtcVoiceMediaChannel : : DeleteVoEChannel ( int channel ) {
2013-08-05 20:36:57 +00:00
if ( engine ( ) - > voe ( ) - > base ( ) - > DeleteChannel ( channel ) = = - 1 ) {
LOG_RTCERR1 ( DeleteChannel , channel ) ;
return false ;
}
2013-07-10 00:45:36 +00:00
return true ;
}
bool WebRtcVoiceMediaChannel : : AddSendStream ( const StreamParams & sp ) {
2016-03-08 14:24:13 -08:00
TRACE_EVENT0 ( " webrtc " , " WebRtcVoiceMediaChannel::AddSendStream " ) ;
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2015-10-20 15:49:38 -07:00
LOG ( LS_INFO ) < < " AddSendStream: " < < sp . ToString ( ) ;
uint32_t ssrc = sp . first_ssrc ( ) ;
RTC_DCHECK ( 0 ! = ssrc ) ;
if ( GetSendChannelId ( ssrc ) ! = - 1 ) {
LOG ( LS_ERROR ) < < " Stream already exists with ssrc " < < ssrc ;
2013-07-10 00:45:36 +00:00
return false ;
}
2015-10-20 15:49:38 -07:00
// Create a new channel for sending audio data.
int channel = CreateVoEChannel ( ) ;
if ( channel = = - 1 ) {
return false ;
2013-08-05 20:36:57 +00:00
}
2015-10-21 13:01:53 -07:00
// Save the channel to send_streams_, so that RemoveSendStream() can still
2013-08-05 20:36:57 +00:00
// delete the channel in case failure happens below.
2014-02-03 16:57:16 +00:00
webrtc : : AudioTransport * audio_transport =
engine ( ) - > voe ( ) - > base ( ) - > audio_transport ( ) ;
2016-04-29 00:57:13 -07:00
2016-10-31 04:08:32 -07:00
rtc : : Optional < std : : string > audio_network_adaptor_config =
GetAudioNetworkAdaptorConfig ( options_ ) ;
2016-04-07 22:59:22 -07:00
WebRtcAudioSendStream * stream = new WebRtcAudioSendStream (
2016-06-14 10:02:41 -07:00
channel , audio_transport , ssrc , sp . cname , send_codec_spec_ ,
2016-10-31 04:08:32 -07:00
send_rtp_extensions_ , max_send_bitrate_bps_ , audio_network_adaptor_config ,
2017-04-27 02:08:52 -07:00
call_ , this , engine ( ) - > encoder_factory_ ) ;
2016-04-07 22:59:22 -07:00
send_streams_ . insert ( std : : make_pair ( ssrc , stream ) ) ;
2013-08-05 20:36:57 +00:00
2016-06-16 13:07:33 -07:00
// At this point the stream's local SSRC has been updated. If it is the first
// send stream, make sure that all the receive streams are updated with the
// same SSRC in order to send receiver reports.
2015-10-21 13:01:53 -07:00
if ( send_streams_ . size ( ) = = 1 ) {
2015-10-20 15:49:38 -07:00
receiver_reports_ssrc_ = ssrc ;
2016-06-16 13:07:33 -07:00
for ( const auto & kv : recv_streams_ ) {
// TODO(solenberg): Allow applications to set the RTCP SSRC of receive
// streams instead, so we can avoid recreating the streams here.
kv . second - > RecreateAudioReceiveStream ( ssrc ) ;
2013-07-10 00:45:36 +00:00
}
}
2016-03-08 12:37:39 -08:00
send_streams_ [ ssrc ] - > SetSend ( send_ ) ;
return true ;
2013-07-10 00:45:36 +00:00
}
Use suffixed {uint,int}{8,16,32,64}_t types.
Removes the use of uint8, etc. in favor of uint8_t.
BUG=webrtc:5024
R=henrik.lundin@webrtc.org, henrikg@webrtc.org, perkj@webrtc.org, solenberg@webrtc.org, stefan@webrtc.org, tina.legrand@webrtc.org
Review URL: https://codereview.webrtc.org/1362503003 .
Cr-Commit-Position: refs/heads/master@{#10196}
2015-10-07 12:23:21 +02:00
bool WebRtcVoiceMediaChannel : : RemoveSendStream ( uint32_t ssrc ) {
2016-03-08 14:24:13 -08:00
TRACE_EVENT0 ( " webrtc " , " WebRtcVoiceMediaChannel::RemoveSendStream " ) ;
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2015-11-16 07:34:50 -08:00
LOG ( LS_INFO ) < < " RemoveSendStream: " < < ssrc ;
2015-10-21 13:01:53 -07:00
auto it = send_streams_ . find ( ssrc ) ;
if ( it = = send_streams_ . end ( ) ) {
2013-08-05 20:36:57 +00:00
LOG ( LS_WARNING ) < < " Try to remove stream with ssrc " < < ssrc
< < " which doesn't exist. " ;
2013-07-10 00:45:36 +00:00
return false ;
}
2013-07-26 19:17:59 +00:00
2016-03-08 12:37:39 -08:00
it - > second - > SetSend ( false ) ;
2013-08-05 20:36:57 +00:00
2016-11-14 11:30:07 -08:00
// TODO(solenberg): If we're removing the receiver_reports_ssrc_ stream, find
// the first active send stream and use that instead, reassociating receive
// streams.
2015-11-20 09:59:34 -08:00
// Clean up and delete the send stream+channel.
2016-03-08 12:37:39 -08:00
int channel = it - > second - > channel ( ) ;
2015-10-20 15:49:38 -07:00
LOG ( LS_INFO ) < < " Removing audio send stream " < < ssrc
< < " with VoiceEngine channel # " < < channel < < " . " ;
2015-11-20 09:59:34 -08:00
delete it - > second ;
send_streams_ . erase ( it ) ;
if ( ! DeleteVoEChannel ( channel ) ) {
2015-10-20 15:49:38 -07:00
return false ;
2013-08-05 20:36:57 +00:00
}
2015-10-21 13:01:53 -07:00
if ( send_streams_ . empty ( ) ) {
2016-03-08 12:37:39 -08:00
SetSend ( false ) ;
2015-10-20 15:49:38 -07:00
}
2013-07-10 00:45:36 +00:00
return true ;
}
bool WebRtcVoiceMediaChannel : : AddRecvStream ( const StreamParams & sp ) {
2016-03-08 14:24:13 -08:00
TRACE_EVENT0 ( " webrtc " , " WebRtcVoiceMediaChannel::AddRecvStream " ) ;
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2015-10-07 01:40:33 -07:00
LOG ( LS_INFO ) < < " AddRecvStream: " < < sp . ToString ( ) ;
2015-10-09 01:37:09 -07:00
if ( ! ValidateStreamParams ( sp ) ) {
2013-07-10 00:45:36 +00:00
return false ;
2015-10-09 01:37:09 -07:00
}
2013-07-10 00:45:36 +00:00
2015-11-20 09:59:34 -08:00
const uint32_t ssrc = sp . first_ssrc ( ) ;
2013-10-07 23:32:02 +00:00
if ( ssrc = = 0 ) {
2015-10-09 01:37:09 -07:00
LOG ( LS_WARNING ) < < " AddRecvStream with ssrc==0 is not supported. " ;
2013-10-07 23:32:02 +00:00
return false ;
}
2017-03-01 11:29:29 -08:00
// If this stream was previously received unsignaled, we promote it, possibly
// recreating the AudioReceiveStream, if sync_label has changed.
if ( MaybeDeregisterUnsignaledRecvStream ( ssrc ) ) {
2017-02-17 12:01:14 -08:00
recv_streams_ [ ssrc ] - > MaybeRecreateAudioReceiveStream ( sp . sync_label ) ;
return true ;
2015-10-13 03:58:19 -07:00
}
2015-10-09 01:37:09 -07:00
2015-11-20 09:59:34 -08:00
if ( GetReceiveChannelId ( ssrc ) ! = - 1 ) {
2013-07-26 19:17:59 +00:00
LOG ( LS_ERROR ) < < " Stream already exists with ssrc " < < ssrc ;
2013-07-10 00:45:36 +00:00
return false ;
}
2015-05-07 14:07:48 +02:00
2013-07-10 00:45:36 +00:00
// Create a new channel for receiving audio data.
2015-11-20 09:59:34 -08:00
const int channel = CreateVoEChannel ( ) ;
2013-07-10 00:45:36 +00:00
if ( channel = = - 1 ) {
return false ;
}
2015-05-13 14:14:42 +02:00
2016-02-04 04:12:24 -08:00
recv_streams_ . insert ( std : : make_pair (
2017-03-27 07:15:49 -07:00
ssrc ,
new WebRtcAudioReceiveStream (
channel , ssrc , receiver_reports_ssrc_ , recv_transport_cc_enabled_ ,
recv_nack_enabled_ , sp . sync_label , recv_rtp_extensions_ , call_ , this ,
engine ( ) - > decoder_factory_ , decoder_map_ ) ) ) ;
2016-08-04 05:28:21 -07:00
recv_streams_ [ ssrc ] - > SetPlayout ( playout_ ) ;
2015-11-20 09:59:34 -08:00
2015-10-13 03:58:19 -07:00
return true ;
2013-07-10 00:45:36 +00:00
}
Use suffixed {uint,int}{8,16,32,64}_t types.
Removes the use of uint8, etc. in favor of uint8_t.
BUG=webrtc:5024
R=henrik.lundin@webrtc.org, henrikg@webrtc.org, perkj@webrtc.org, solenberg@webrtc.org, stefan@webrtc.org, tina.legrand@webrtc.org
Review URL: https://codereview.webrtc.org/1362503003 .
Cr-Commit-Position: refs/heads/master@{#10196}
2015-10-07 12:23:21 +02:00
bool WebRtcVoiceMediaChannel : : RemoveRecvStream ( uint32_t ssrc ) {
2016-03-08 14:24:13 -08:00
TRACE_EVENT0 ( " webrtc " , " WebRtcVoiceMediaChannel::RemoveRecvStream " ) ;
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2015-10-07 01:40:33 -07:00
LOG ( LS_INFO ) < < " RemoveRecvStream: " < < ssrc ;
2015-11-20 09:59:34 -08:00
const auto it = recv_streams_ . find ( ssrc ) ;
if ( it = = recv_streams_ . end ( ) ) {
2013-08-05 20:36:57 +00:00
LOG ( LS_WARNING ) < < " Try to remove stream with ssrc " < < ssrc
< < " which doesn't exist. " ;
2013-07-26 19:17:59 +00:00
return false ;
2013-08-05 20:36:57 +00:00
}
2013-07-10 00:45:36 +00:00
2017-03-01 11:29:29 -08:00
MaybeDeregisterUnsignaledRecvStream ( ssrc ) ;
2013-07-26 19:17:59 +00:00
2015-11-20 09:59:34 -08:00
const int channel = it - > second - > channel ( ) ;
// Clean up and delete the receive stream+channel.
LOG ( LS_INFO ) < < " Removing audio receive stream " < < ssrc
2014-02-03 16:57:16 +00:00
< < " with VoiceEngine channel # " < < channel < < " . " ;
2015-12-12 01:37:01 +01:00
it - > second - > SetRawAudioSink ( nullptr ) ;
2015-11-20 09:59:34 -08:00
delete it - > second ;
recv_streams_ . erase ( it ) ;
return DeleteVoEChannel ( channel ) ;
2013-07-26 19:17:59 +00:00
}
2016-03-08 12:37:39 -08:00
bool WebRtcVoiceMediaChannel : : SetLocalSource ( uint32_t ssrc ,
AudioSource * source ) {
2015-10-21 13:01:53 -07:00
auto it = send_streams_ . find ( ssrc ) ;
if ( it = = send_streams_ . end ( ) ) {
2016-03-08 12:37:39 -08:00
if ( source ) {
// Return an error if trying to set a valid source with an invalid ssrc.
LOG ( LS_ERROR ) < < " SetLocalSource failed with ssrc " < < ssrc ;
2013-08-05 20:36:57 +00:00
return false ;
}
2013-07-26 19:17:59 +00:00
2013-08-05 20:36:57 +00:00
// The channel likely has gone away, do nothing.
return true ;
2013-07-26 19:17:59 +00:00
}
2013-07-10 00:45:36 +00:00
2016-03-08 12:37:39 -08:00
if ( source ) {
it - > second - > SetSource ( source ) ;
2015-10-13 03:58:19 -07:00
} else {
2016-03-08 12:37:39 -08:00
it - > second - > ClearSource ( ) ;
2015-10-13 03:58:19 -07:00
}
2013-07-26 19:17:59 +00:00
2013-07-10 00:45:36 +00:00
return true ;
}
2017-03-01 17:02:23 -08:00
// TODO(solenberg): Remove, once AudioMonitor is gone.
2013-07-10 00:45:36 +00:00
bool WebRtcVoiceMediaChannel : : GetActiveStreams (
AudioInfo : : StreamList * actives ) {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2013-07-10 00:45:36 +00:00
actives - > clear ( ) ;
2015-11-20 09:59:34 -08:00
for ( const auto & ch : recv_streams_ ) {
2017-03-01 17:02:23 -08:00
int level = ch . second - > GetOutputLevel ( ) ;
2013-07-10 00:45:36 +00:00
if ( level > 0 ) {
2015-08-26 10:45:53 +02:00
actives - > push_back ( std : : make_pair ( ch . first , level ) ) ;
2013-07-10 00:45:36 +00:00
}
}
return true ;
}
2017-03-01 17:02:23 -08:00
// TODO(solenberg): Remove, once AudioMonitor is gone.
2013-07-10 00:45:36 +00:00
int WebRtcVoiceMediaChannel : : GetOutputLevel ( ) {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2015-10-13 03:58:19 -07:00
int highest = 0 ;
2015-11-20 09:59:34 -08:00
for ( const auto & ch : recv_streams_ ) {
2017-03-01 17:02:23 -08:00
highest = std : : max ( ch . second - > GetOutputLevel ( ) , highest ) ;
2013-07-10 00:45:36 +00:00
}
return highest ;
}
2015-10-09 02:32:53 -07:00
bool WebRtcVoiceMediaChannel : : SetOutputVolume ( uint32_t ssrc , double volume ) {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2017-03-01 11:29:29 -08:00
std : : vector < uint32_t > ssrcs ( 1 , ssrc ) ;
2017-04-20 19:25:07 -07:00
// SSRC of 0 represents the default receive stream.
2015-10-13 03:58:19 -07:00
if ( ssrc = = 0 ) {
default_recv_volume_ = volume ;
2017-03-01 11:29:29 -08:00
ssrcs = unsignaled_recv_ssrcs_ ;
2015-10-13 03:58:19 -07:00
}
2017-03-01 11:29:29 -08:00
for ( uint32_t ssrc : ssrcs ) {
const auto it = recv_streams_ . find ( ssrc ) ;
if ( it = = recv_streams_ . end ( ) ) {
LOG ( LS_WARNING ) < < " SetOutputVolume: no recv stream " < < ssrc ;
return false ;
}
it - > second - > SetOutputVolume ( volume ) ;
LOG ( LS_INFO ) < < " SetOutputVolume() to " < < volume
< < " for recv stream with ssrc " < < ssrc ;
2013-07-10 00:45:36 +00:00
}
return true ;
}
bool WebRtcVoiceMediaChannel : : CanInsertDtmf ( ) {
2015-12-04 15:22:19 +01:00
return dtmf_payload_type_ ? true : false ;
2013-07-10 00:45:36 +00:00
}
2015-12-02 12:35:09 -08:00
bool WebRtcVoiceMediaChannel : : InsertDtmf ( uint32_t ssrc , int event ,
int duration ) {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2015-12-04 15:22:19 +01:00
LOG ( LS_INFO ) < < " WebRtcVoiceMediaChannel::InsertDtmf " ;
if ( ! dtmf_payload_type_ ) {
2013-07-10 00:45:36 +00:00
return false ;
}
2015-12-04 15:22:19 +01:00
// Figure out which WebRtcAudioSendStream to send the event on.
auto it = ssrc ! = 0 ? send_streams_ . find ( ssrc ) : send_streams_ . begin ( ) ;
if ( it = = send_streams_ . end ( ) ) {
LOG ( LS_WARNING ) < < " The specified ssrc " < < ssrc < < " is not in use. " ;
return false ;
2013-07-10 00:45:36 +00:00
}
2015-12-04 15:22:19 +01:00
if ( event < kMinTelephoneEventCode | |
event > kMaxTelephoneEventCode ) {
LOG ( LS_WARNING ) < < " DTMF event code " < < event < < " out of range. " ;
2015-12-02 12:35:09 -08:00
return false ;
}
2016-11-17 05:25:37 -08:00
RTC_DCHECK_NE ( - 1 , dtmf_payload_freq_ ) ;
return it - > second - > SendTelephoneEvent ( * dtmf_payload_type_ , dtmf_payload_freq_ ,
event , duration ) ;
2013-07-10 00:45:36 +00:00
}
2013-12-13 00:21:03 +00:00
void WebRtcVoiceMediaChannel : : OnPacketReceived (
2016-03-20 06:15:43 -07:00
rtc : : CopyOnWriteBuffer * packet , const rtc : : PacketTime & packet_time ) {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2015-05-07 14:07:48 +02:00
2016-04-29 00:57:13 -07:00
const webrtc : : PacketTime webrtc_packet_time ( packet_time . timestamp ,
packet_time . not_before ) ;
webrtc : : PacketReceiver : : DeliveryStatus delivery_result =
call_ - > Receiver ( ) - > DeliverPacket ( webrtc : : MediaType : : AUDIO ,
packet - > cdata ( ) , packet - > size ( ) ,
webrtc_packet_time ) ;
if ( delivery_result ! = webrtc : : PacketReceiver : : DELIVERY_UNKNOWN_SSRC ) {
return ;
}
2017-03-01 11:29:29 -08:00
// Create an unsignaled receive stream for this previously not received ssrc.
// If there already is N unsignaled receive streams, delete the oldest.
2016-04-29 00:57:13 -07:00
// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5208
2015-10-13 03:58:19 -07:00
uint32_t ssrc = 0 ;
2016-03-20 06:15:43 -07:00
if ( ! GetRtpSsrc ( packet - > cdata ( ) , packet - > size ( ) , & ssrc ) ) {
2015-10-13 03:58:19 -07:00
return ;
}
2017-03-01 11:29:29 -08:00
RTC_DCHECK ( std : : find ( unsignaled_recv_ssrcs_ . begin ( ) ,
unsignaled_recv_ssrcs_ . end ( ) , ssrc ) = = unsignaled_recv_ssrcs_ . end ( ) ) ;
2015-10-13 03:58:19 -07:00
2017-03-01 11:29:29 -08:00
// Add new stream.
2016-04-29 00:57:13 -07:00
StreamParams sp ;
sp . ssrcs . push_back ( ssrc ) ;
2017-03-01 11:29:29 -08:00
LOG ( LS_INFO ) < < " Creating unsignaled receive stream for SSRC= " < < ssrc ;
2016-04-29 00:57:13 -07:00
if ( ! AddRecvStream ( sp ) ) {
2017-03-01 11:29:29 -08:00
LOG ( LS_WARNING ) < < " Could not create unsignaled receive stream. " ;
2016-04-29 00:57:13 -07:00
return ;
2013-07-10 00:45:36 +00:00
}
2017-03-01 11:29:29 -08:00
unsignaled_recv_ssrcs_ . push_back ( ssrc ) ;
RTC_HISTOGRAM_COUNTS_LINEAR (
" WebRTC.Audio.NumOfUnsignaledStreams " , unsignaled_recv_ssrcs_ . size ( ) , 1 ,
100 , 101 ) ;
// Remove oldest unsignaled stream, if we have too many.
if ( unsignaled_recv_ssrcs_ . size ( ) > kMaxUnsignaledRecvStreams ) {
uint32_t remove_ssrc = unsignaled_recv_ssrcs_ . front ( ) ;
LOG ( LS_INFO ) < < " Removing unsignaled receive stream with SSRC= "
< < remove_ssrc ;
RemoveRecvStream ( remove_ssrc ) ;
2017-02-06 13:03:19 -08:00
}
2017-03-01 11:29:29 -08:00
RTC_DCHECK_GE ( kMaxUnsignaledRecvStreams , unsignaled_recv_ssrcs_ . size ( ) ) ;
2017-02-06 13:03:19 -08:00
2017-03-01 11:29:29 -08:00
SetOutputVolume ( ssrc , default_recv_volume_ ) ;
// The default sink can only be attached to one stream at a time, so we hook
// it up to the *latest* unsignaled stream we've seen, in order to support the
// case where the SSRC of one unsignaled stream changes.
2016-04-29 00:57:13 -07:00
if ( default_sink_ ) {
2017-03-01 11:29:29 -08:00
for ( uint32_t drop_ssrc : unsignaled_recv_ssrcs_ ) {
auto it = recv_streams_ . find ( drop_ssrc ) ;
it - > second - > SetRawAudioSink ( nullptr ) ;
}
2016-04-29 00:57:13 -07:00
std : : unique_ptr < webrtc : : AudioSinkInterface > proxy_sink (
new ProxySink ( default_sink_ . get ( ) ) ) ;
2017-03-01 11:29:29 -08:00
SetRawAudioSink ( ssrc , std : : move ( proxy_sink ) ) ;
2016-04-29 00:57:13 -07:00
}
2017-03-01 11:29:29 -08:00
2016-04-29 00:57:13 -07:00
delivery_result = call_ - > Receiver ( ) - > DeliverPacket ( webrtc : : MediaType : : AUDIO ,
packet - > cdata ( ) ,
packet - > size ( ) ,
webrtc_packet_time ) ;
RTC_DCHECK_NE ( webrtc : : PacketReceiver : : DELIVERY_UNKNOWN_SSRC , delivery_result ) ;
2013-07-10 00:45:36 +00:00
}
2013-12-13 00:21:03 +00:00
void WebRtcVoiceMediaChannel : : OnRtcpReceived (
2016-03-20 06:15:43 -07:00
rtc : : CopyOnWriteBuffer * packet , const rtc : : PacketTime & packet_time ) {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2015-05-07 14:07:48 +02:00
2015-09-15 12:26:33 +02:00
// Forward packet to Call as well.
const webrtc : : PacketTime webrtc_packet_time ( packet_time . timestamp ,
packet_time . not_before ) ;
call_ - > Receiver ( ) - > DeliverPacket ( webrtc : : MediaType : : AUDIO ,
2016-03-20 06:15:43 -07:00
packet - > cdata ( ) , packet - > size ( ) , webrtc_packet_time ) ;
2013-07-10 00:45:36 +00:00
}
2016-03-29 17:27:21 -07:00
void WebRtcVoiceMediaChannel : : OnNetworkRouteChanged (
const std : : string & transport_name ,
2016-04-19 15:41:36 -07:00
const rtc : : NetworkRoute & network_route ) {
call_ - > OnNetworkRouteChanged ( transport_name , network_route ) ;
2016-03-29 17:27:21 -07:00
}
Use suffixed {uint,int}{8,16,32,64}_t types.
Removes the use of uint8, etc. in favor of uint8_t.
BUG=webrtc:5024
R=henrik.lundin@webrtc.org, henrikg@webrtc.org, perkj@webrtc.org, solenberg@webrtc.org, stefan@webrtc.org, tina.legrand@webrtc.org
Review URL: https://codereview.webrtc.org/1362503003 .
Cr-Commit-Position: refs/heads/master@{#10196}
2015-10-07 12:23:21 +02:00
bool WebRtcVoiceMediaChannel : : MuteStream ( uint32_t ssrc , bool muted ) {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2016-06-16 10:53:22 -07:00
const auto it = send_streams_ . find ( ssrc ) ;
if ( it = = send_streams_ . end ( ) ) {
2013-07-10 00:45:36 +00:00
LOG ( LS_WARNING ) < < " The specified ssrc " < < ssrc < < " is not in use. " ;
return false ;
}
2016-06-16 10:53:22 -07:00
it - > second - > SetMuted ( muted ) ;
// TODO(solenberg):
2014-07-31 15:08:53 +00:00
// We set the AGC to mute state only when all the channels are muted.
// This implementation is not ideal, instead we should signal the AGC when
// the mic channel is muted/unmuted. We can't do it today because there
// is no good way to know which stream is mapping to the mic channel.
bool all_muted = muted ;
2016-06-16 10:53:22 -07:00
for ( const auto & kv : send_streams_ ) {
all_muted = all_muted & & kv . second - > muted ( ) ;
2014-07-31 15:08:53 +00:00
}
2016-10-26 05:12:24 -07:00
engine ( ) - > apm ( ) - > set_output_will_be_muted ( all_muted ) ;
2014-07-31 15:08:53 +00:00
2013-07-10 00:45:36 +00:00
return true ;
}
2016-04-27 14:17:10 -07:00
bool WebRtcVoiceMediaChannel : : SetMaxSendBitrate ( int bps ) {
LOG ( LS_INFO ) < < " WebRtcVoiceMediaChannel::SetMaxSendBitrate. " ;
max_send_bitrate_bps_ = bps ;
2016-10-20 03:27:12 -07:00
bool success = true ;
2016-04-07 22:59:22 -07:00
for ( const auto & kv : send_streams_ ) {
2016-10-20 03:27:12 -07:00
if ( ! kv . second - > SetMaxSendBitrate ( max_send_bitrate_bps_ ) ) {
success = false ;
2016-04-07 22:59:22 -07:00
}
2013-07-10 00:45:36 +00:00
}
2016-10-20 03:27:12 -07:00
return success ;
2013-07-10 00:45:36 +00:00
}
2016-03-22 15:32:27 -07:00
void WebRtcVoiceMediaChannel : : OnReadyToSend ( bool ready ) {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
LOG ( LS_VERBOSE ) < < " OnReadyToSend: " < < ( ready ? " Ready. " : " Not ready. " ) ;
call_ - > SignalChannelNetworkState (
webrtc : : MediaType : : AUDIO ,
ready ? webrtc : : kNetworkUp : webrtc : : kNetworkDown ) ;
}
2016-11-08 02:50:09 -08:00
void WebRtcVoiceMediaChannel : : OnTransportOverheadChanged (
int transport_overhead_per_packet ) {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
call_ - > OnTransportOverheadChanged ( webrtc : : MediaType : : AUDIO ,
transport_overhead_per_packet ) ;
}
2013-07-10 00:45:36 +00:00
bool WebRtcVoiceMediaChannel : : GetStats ( VoiceMediaInfo * info ) {
2016-03-08 14:24:13 -08:00
TRACE_EVENT0 ( " webrtc " , " WebRtcVoiceMediaChannel::GetStats " ) ;
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2015-10-27 03:35:21 -07:00
RTC_DCHECK ( info ) ;
2015-10-07 01:40:33 -07:00
2015-10-27 03:35:21 -07:00
// Get SSRC and stats for each sender.
2016-11-17 23:43:29 -08:00
RTC_DCHECK_EQ ( info - > senders . size ( ) , 0U ) ;
2015-10-27 03:35:21 -07:00
for ( const auto & stream : send_streams_ ) {
webrtc : : AudioSendStream : : Stats stats = stream . second - > GetStats ( ) ;
2013-08-05 20:36:57 +00:00
VoiceSenderInfo sinfo ;
2015-10-27 03:35:21 -07:00
sinfo . add_ssrc ( stats . local_ssrc ) ;
sinfo . bytes_sent = stats . bytes_sent ;
sinfo . packets_sent = stats . packets_sent ;
sinfo . packets_lost = stats . packets_lost ;
sinfo . fraction_lost = stats . fraction_lost ;
sinfo . codec_name = stats . codec_name ;
2016-11-17 23:43:29 -08:00
sinfo . codec_payload_type = stats . codec_payload_type ;
2015-10-27 03:35:21 -07:00
sinfo . ext_seqnum = stats . ext_seqnum ;
sinfo . jitter_ms = stats . jitter_ms ;
sinfo . rtt_ms = stats . rtt_ms ;
sinfo . audio_level = stats . audio_level ;
2017-07-14 12:17:49 -07:00
sinfo . total_input_energy = stats . total_input_energy ;
sinfo . total_input_duration = stats . total_input_duration ;
2015-10-27 03:35:21 -07:00
sinfo . aec_quality_min = stats . aec_quality_min ;
sinfo . echo_delay_median_ms = stats . echo_delay_median_ms ;
sinfo . echo_delay_std_ms = stats . echo_delay_std_ms ;
sinfo . echo_return_loss = stats . echo_return_loss ;
sinfo . echo_return_loss_enhancement = stats . echo_return_loss_enhancement ;
2016-10-21 04:10:03 -07:00
sinfo . residual_echo_likelihood = stats . residual_echo_likelihood ;
2017-01-15 08:29:46 -08:00
sinfo . residual_echo_likelihood_recent_max =
stats . residual_echo_likelihood_recent_max ;
2016-03-08 12:37:39 -08:00
sinfo . typing_noise_detected = ( send_ ? stats . typing_noise_detected : false ) ;
2013-08-05 20:36:57 +00:00
info - > senders . push_back ( sinfo ) ;
}
2013-07-10 00:45:36 +00:00
2015-10-27 03:35:21 -07:00
// Get SSRC and stats for each receiver.
2016-11-17 23:43:29 -08:00
RTC_DCHECK_EQ ( info - > receivers . size ( ) , 0U ) ;
2015-11-20 09:59:34 -08:00
for ( const auto & stream : recv_streams_ ) {
2015-10-22 10:49:27 +02:00
webrtc : : AudioReceiveStream : : Stats stats = stream . second - > GetStats ( ) ;
VoiceReceiverInfo rinfo ;
rinfo . add_ssrc ( stats . remote_ssrc ) ;
rinfo . bytes_rcvd = stats . bytes_rcvd ;
rinfo . packets_rcvd = stats . packets_rcvd ;
rinfo . packets_lost = stats . packets_lost ;
rinfo . fraction_lost = stats . fraction_lost ;
rinfo . codec_name = stats . codec_name ;
2016-11-17 23:43:29 -08:00
rinfo . codec_payload_type = stats . codec_payload_type ;
2015-10-22 10:49:27 +02:00
rinfo . ext_seqnum = stats . ext_seqnum ;
rinfo . jitter_ms = stats . jitter_ms ;
rinfo . jitter_buffer_ms = stats . jitter_buffer_ms ;
rinfo . jitter_buffer_preferred_ms = stats . jitter_buffer_preferred_ms ;
rinfo . delay_estimate_ms = stats . delay_estimate_ms ;
rinfo . audio_level = stats . audio_level ;
2017-07-14 12:17:49 -07:00
rinfo . total_output_energy = stats . total_output_energy ;
2017-08-24 17:15:13 -07:00
rinfo . total_samples_received = stats . total_samples_received ;
2017-07-14 12:17:49 -07:00
rinfo . total_output_duration = stats . total_output_duration ;
2017-08-24 17:15:13 -07:00
rinfo . concealed_samples = stats . concealed_samples ;
2015-10-22 10:49:27 +02:00
rinfo . expand_rate = stats . expand_rate ;
rinfo . speech_expand_rate = stats . speech_expand_rate ;
rinfo . secondary_decoded_rate = stats . secondary_decoded_rate ;
2017-08-28 13:51:27 +02:00
rinfo . secondary_discarded_rate = stats . secondary_discarded_rate ;
2015-10-22 10:49:27 +02:00
rinfo . accelerate_rate = stats . accelerate_rate ;
rinfo . preemptive_expand_rate = stats . preemptive_expand_rate ;
rinfo . decoding_calls_to_silence_generator =
stats . decoding_calls_to_silence_generator ;
rinfo . decoding_calls_to_neteq = stats . decoding_calls_to_neteq ;
rinfo . decoding_normal = stats . decoding_normal ;
rinfo . decoding_plc = stats . decoding_plc ;
rinfo . decoding_cng = stats . decoding_cng ;
rinfo . decoding_plc_cng = stats . decoding_plc_cng ;
2016-09-20 01:47:12 -07:00
rinfo . decoding_muted_output = stats . decoding_muted_output ;
2015-10-22 10:49:27 +02:00
rinfo . capture_start_ntp_time_ms = stats . capture_start_ntp_time_ms ;
info - > receivers . push_back ( rinfo ) ;
2013-07-10 00:45:36 +00:00
}
2016-11-17 23:43:29 -08:00
// Get codec info
for ( const AudioCodec & codec : send_codecs_ ) {
webrtc : : RtpCodecParameters codec_params = codec . ToCodecParameters ( ) ;
info - > send_codecs . insert (
std : : make_pair ( codec_params . payload_type , std : : move ( codec_params ) ) ) ;
}
for ( const AudioCodec & codec : recv_codecs_ ) {
webrtc : : RtpCodecParameters codec_params = codec . ToCodecParameters ( ) ;
info - > receive_codecs . insert (
std : : make_pair ( codec_params . payload_type , std : : move ( codec_params ) ) ) ;
}
2013-07-10 00:45:36 +00:00
return true ;
}
2015-12-12 01:37:01 +01:00
void WebRtcVoiceMediaChannel : : SetRawAudioSink (
uint32_t ssrc ,
2016-02-26 03:00:35 -08:00
std : : unique_ptr < webrtc : : AudioSinkInterface > sink ) {
2015-12-12 01:37:01 +01:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2016-01-15 09:20:04 -08:00
LOG ( LS_VERBOSE ) < < " WebRtcVoiceMediaChannel::SetRawAudioSink: ssrc: " < < ssrc
< < " " < < ( sink ? " (ptr) " : " NULL " ) ;
if ( ssrc = = 0 ) {
2017-03-01 11:29:29 -08:00
if ( ! unsignaled_recv_ssrcs_ . empty ( ) ) {
2016-02-26 03:00:35 -08:00
std : : unique_ptr < webrtc : : AudioSinkInterface > proxy_sink (
2016-01-15 09:20:04 -08:00
sink ? new ProxySink ( sink . get ( ) ) : nullptr ) ;
2017-03-01 11:29:29 -08:00
SetRawAudioSink ( unsignaled_recv_ssrcs_ . back ( ) , std : : move ( proxy_sink ) ) ;
2016-01-15 09:20:04 -08:00
}
default_sink_ = std : : move ( sink ) ;
return ;
}
2015-12-12 01:37:01 +01:00
const auto it = recv_streams_ . find ( ssrc ) ;
if ( it = = recv_streams_ . end ( ) ) {
2017-03-01 11:29:29 -08:00
LOG ( LS_WARNING ) < < " SetRawAudioSink: no recv stream " < < ssrc ;
2015-12-12 01:37:01 +01:00
return ;
}
2016-01-13 12:00:26 -08:00
it - > second - > SetRawAudioSink ( std : : move ( sink ) ) ;
2015-12-12 01:37:01 +01:00
}
Reland of Implemented the GetSources() in native code. (patchset #1 id:1 of https://codereview.webrtc.org/2809613002/ )
Reason for revert:
Re-land, reverting did not fix bug.
https://bugs.chromium.org/p/webrtc/issues/detail?id=7465
Original issue's description:
> Revert of Implemented the GetSources() in native code. (patchset #11 id:510001 of https://codereview.webrtc.org/2770233003/ )
>
> Reason for revert:
> Suspected of WebRtcApprtcBrowserTest.MANUAL_WorksOnApprtc breakage, see
>
> https://bugs.chromium.org/p/webrtc/issues/detail?id=7465
>
> Original issue's description:
> > Added the GetSources() to the RtpReceiverInterface and implemented
> > it for the AudioRtpReceiver.
> >
> > This method returns a vector of RtpSource(both CSRC source and SSRC
> > source) which contains the ID of a source, the timestamp, the source
> > type (SSRC or CSRC) and the audio level.
> >
> > The RtpSource objects are buffered and maintained by the
> > RtpReceiver in webrtc/modules/rtp_rtcp/. When the method is called,
> > the info of the contributing source will be pulled along the object
> > chain:
> > AudioRtpReceiver -> VoiceChannel -> WebRtcVoiceMediaChannel ->
> > AudioReceiveStream -> voe::Channel -> RtpRtcp module
> >
> > Spec:https://w3c.github.io/webrtc-pc/archives/20151006/webrtc.html#widl-RTCRtpReceiver-getContributingSources-sequence-RTCRtpContributingSource
> >
> > BUG=chromium:703122
> > TBR=stefan@webrtc.org, danilchap@webrtc.org
> >
> > Review-Url: https://codereview.webrtc.org/2770233003
> > Cr-Commit-Position: refs/heads/master@{#17591}
> > Committed: https://chromium.googlesource.com/external/webrtc/+/292084c3765d9f3ee406ca2ec86eae206b540053
>
> TBR=deadbeef@webrtc.org,solenberg@webrtc.org,hbos@webrtc.org,philipel@webrtc.org,stefan@webrtc.org,danilchap@webrtc.org,zhihuang@webrtc.org
> # Not skipping CQ checks because original CL landed more than 1 days ago.
> BUG=chromium:703122
>
> Review-Url: https://codereview.webrtc.org/2809613002
> Cr-Commit-Position: refs/heads/master@{#17616}
> Committed: https://chromium.googlesource.com/external/webrtc/+/fbcc5cb3869d1370008e40f24fc03ac8fb69c675
TBR=deadbeef@webrtc.org,solenberg@webrtc.org,philipel@webrtc.org,stefan@webrtc.org,danilchap@webrtc.org,zhihuang@webrtc.org,olka@webrtc.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=chromium:703122
Review-Url: https://codereview.webrtc.org/2810623003
Cr-Commit-Position: refs/heads/master@{#17621}
2017-04-10 07:39:05 -07:00
std : : vector < webrtc : : RtpSource > WebRtcVoiceMediaChannel : : GetSources (
uint32_t ssrc ) const {
auto it = recv_streams_ . find ( ssrc ) ;
RTC_DCHECK ( it ! = recv_streams_ . end ( ) )
< < " Attempting to get contributing sources for SSRC: " < < ssrc
< < " which doesn't exist. " ;
return it - > second - > GetSources ( ) ;
}
Use suffixed {uint,int}{8,16,32,64}_t types.
Removes the use of uint8, etc. in favor of uint8_t.
BUG=webrtc:5024
R=henrik.lundin@webrtc.org, henrikg@webrtc.org, perkj@webrtc.org, solenberg@webrtc.org, stefan@webrtc.org, tina.legrand@webrtc.org
Review URL: https://codereview.webrtc.org/1362503003 .
Cr-Commit-Position: refs/heads/master@{#10196}
2015-10-07 12:23:21 +02:00
int WebRtcVoiceMediaChannel : : GetReceiveChannelId ( uint32_t ssrc ) const {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2015-11-20 09:59:34 -08:00
const auto it = recv_streams_ . find ( ssrc ) ;
if ( it ! = recv_streams_ . end ( ) ) {
2014-02-03 16:57:16 +00:00
return it - > second - > channel ( ) ;
2015-10-13 03:06:58 -07:00
}
2015-10-13 03:58:19 -07:00
return - 1 ;
2013-07-10 00:45:36 +00:00
}
Use suffixed {uint,int}{8,16,32,64}_t types.
Removes the use of uint8, etc. in favor of uint8_t.
BUG=webrtc:5024
R=henrik.lundin@webrtc.org, henrikg@webrtc.org, perkj@webrtc.org, solenberg@webrtc.org, stefan@webrtc.org, tina.legrand@webrtc.org
Review URL: https://codereview.webrtc.org/1362503003 .
Cr-Commit-Position: refs/heads/master@{#10196}
2015-10-07 12:23:21 +02:00
int WebRtcVoiceMediaChannel : : GetSendChannelId ( uint32_t ssrc ) const {
2015-11-06 15:34:49 -08:00
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
2015-10-21 13:01:53 -07:00
const auto it = send_streams_ . find ( ssrc ) ;
if ( it ! = send_streams_ . end ( ) ) {
2014-02-03 16:57:16 +00:00
return it - > second - > channel ( ) ;
2015-10-13 03:06:58 -07:00
}
2013-08-05 20:36:57 +00:00
return - 1 ;
2013-07-10 00:45:36 +00:00
}
2017-03-01 11:29:29 -08:00
bool WebRtcVoiceMediaChannel : :
MaybeDeregisterUnsignaledRecvStream ( uint32_t ssrc ) {
RTC_DCHECK ( worker_thread_checker_ . CalledOnValidThread ( ) ) ;
auto it = std : : find ( unsignaled_recv_ssrcs_ . begin ( ) ,
unsignaled_recv_ssrcs_ . end ( ) ,
ssrc ) ;
if ( it ! = unsignaled_recv_ssrcs_ . end ( ) ) {
unsignaled_recv_ssrcs_ . erase ( it ) ;
return true ;
}
return false ;
}
2013-07-10 00:45:36 +00:00
} // namespace cricket
# endif // HAVE_WEBRTC_VOICE