Stop using deprecated constraints-based version of CreateAudioSource.

Also did some slight refactoring of the code that turns constraints
into rtc::Optionals. Used a template method to avoid code duplication,
and used the same pattern for "CopyConstraintsIntoAudioOptions" as was
being used for "CopyConstraintsIntoRtcConfiguration".

BUG=webrtc:6752

Review-Url: https://codereview.webrtc.org/2628523003
Cr-Commit-Position: refs/heads/master@{#16063}
This commit is contained in:
deadbeef
2017-01-13 11:47:56 -08:00
committed by Commit bot
parent 8e814d7906
commit fe0fd41bb9
5 changed files with 136 additions and 151 deletions

View File

@ -20,78 +20,6 @@ using webrtc::MediaSourceInterface;
namespace webrtc {
namespace {
// Convert constraints to audio options. Return false if constraints are
// invalid.
void FromConstraints(const MediaConstraintsInterface::Constraints& constraints,
cricket::AudioOptions* options) {
// This design relies on the fact that all the audio constraints are actually
// "options", i.e. boolean-valued and always satisfiable. If the constraints
// are extended to include non-boolean values or actual format constraints,
// a different algorithm will be required.
struct {
const char* name;
rtc::Optional<bool>& value;
} key_to_value[] = {
{MediaConstraintsInterface::kGoogEchoCancellation,
options->echo_cancellation},
{MediaConstraintsInterface::kExtendedFilterEchoCancellation,
options->extended_filter_aec},
{MediaConstraintsInterface::kDAEchoCancellation,
options->delay_agnostic_aec},
{MediaConstraintsInterface::kAutoGainControl, options->auto_gain_control},
{MediaConstraintsInterface::kExperimentalAutoGainControl,
options->experimental_agc},
{MediaConstraintsInterface::kNoiseSuppression,
options->noise_suppression},
{MediaConstraintsInterface::kExperimentalNoiseSuppression,
options->experimental_ns},
{MediaConstraintsInterface::kIntelligibilityEnhancer,
options->intelligibility_enhancer},
{MediaConstraintsInterface::kLevelControl, options->level_control},
{MediaConstraintsInterface::kHighpassFilter, options->highpass_filter},
{MediaConstraintsInterface::kTypingNoiseDetection,
options->typing_detection},
{MediaConstraintsInterface::kAudioMirroring, options->stereo_swapping}
};
for (const auto& constraint : constraints) {
// Set non-boolean constraints.
if (0 == constraint.key.compare(
MediaConstraintsInterface::kLevelControlInitialPeakLevelDBFS)) {
float level_control_initial_peak_level_dbfs = 0.0f;
if (rtc::FromString(constraint.value,
&level_control_initial_peak_level_dbfs)) {
options->level_control_initial_peak_level_dbfs =
rtc::Optional<float>(level_control_initial_peak_level_dbfs);
}
continue;
}
if (constraint.key.compare(
MediaConstraintsInterface::kAudioNetworkAdaptorConfig) == 0) {
// When |kAudioNetworkAdaptorConfig| is defined, it both means that audio
// network adaptor is desired, and provides the config string.
options->audio_network_adaptor = rtc::Optional<bool>(true);
options->audio_network_adaptor_config =
rtc::Optional<std::string>(constraint.value);
continue;
}
// Parse boolean value.
bool value = false;
if (!rtc::FromString(constraint.value, &value))
continue;
for (auto& entry : key_to_value) {
if (constraint.key.compare(entry.name) == 0)
entry.value = rtc::Optional<bool>(value);
}
}
}
} // namespace
rtc::scoped_refptr<LocalAudioSource> LocalAudioSource::Create(
const PeerConnectionFactoryInterface::Options& options,
const MediaConstraintsInterface* constraints) {
@ -113,16 +41,7 @@ rtc::scoped_refptr<LocalAudioSource> LocalAudioSource::Create(
void LocalAudioSource::Initialize(
const PeerConnectionFactoryInterface::Options& options,
const MediaConstraintsInterface* constraints) {
if (!constraints)
return;
// Apply optional constraints first, they will be overwritten by mandatory
// constraints.
FromConstraints(constraints->GetOptional(), &options_);
cricket::AudioOptions mandatory_options;
FromConstraints(constraints->GetMandatory(), &mandatory_options);
options_.SetAll(mandatory_options);
CopyConstraintsIntoAudioOptions(constraints, &options_);
}
void LocalAudioSource::Initialize(

View File

@ -13,6 +13,65 @@
#include "webrtc/api/peerconnectioninterface.h"
#include "webrtc/base/stringencode.h"
namespace {
// Find the highest-priority instance of the T-valued constraint named by
// |key| and return its value as |value|. |constraints| can be null.
// If |mandatory_constraints| is non-null, it is incremented if the key appears
// among the mandatory constraints.
// Returns true if the key was found and has a valid value for type T.
// If the key appears multiple times as an optional constraint, appearances
// after the first are ignored.
// Note: Because this uses FindFirst, repeated optional constraints whose
// first instance has an unrecognized value are not handled precisely in
// accordance with the specification.
template <typename T>
bool FindConstraint(const webrtc::MediaConstraintsInterface* constraints,
const std::string& key,
T* value,
size_t* mandatory_constraints) {
std::string string_value;
if (!FindConstraint(constraints, key, &string_value, mandatory_constraints)) {
return false;
}
return rtc::FromString(string_value, value);
}
// Specialization for std::string, since a string doesn't need conversion.
template <>
bool FindConstraint(const webrtc::MediaConstraintsInterface* constraints,
const std::string& key,
std::string* value,
size_t* mandatory_constraints) {
if (!constraints) {
return false;
}
if (constraints->GetMandatory().FindFirst(key, value)) {
if (mandatory_constraints) {
++*mandatory_constraints;
}
return true;
}
if (constraints->GetOptional().FindFirst(key, value)) {
return true;
}
return false;
}
// Converts a constraint (mandatory takes precedence over optional) to an
// rtc::Optional.
template <typename T>
void ConstraintToOptional(const webrtc::MediaConstraintsInterface* constraints,
const std::string& key,
rtc::Optional<T>* value_out) {
T value;
bool present = FindConstraint<T>(constraints, key, &value, nullptr);
if (present) {
*value_out = rtc::Optional<T>(value);
}
}
}
namespace webrtc {
const char MediaConstraintsInterface::kValueTrue[] = "true";
@ -108,74 +167,17 @@ bool MediaConstraintsInterface::Constraints::FindFirst(
return false;
}
// Find the highest-priority instance of the boolean-valued constraint) named by
// |key| and return its value as |value|. |constraints| can be null.
// If |mandatory_constraints| is non-null, it is incremented if the key appears
// among the mandatory constraints.
// Returns true if the key was found and has a valid boolean value.
// If the key appears multiple times as an optional constraint, appearances
// after the first are ignored.
// Note: Because this uses FindFirst, repeated optional constraints whose
// first instance has an unrecognized value are not handled precisely in
// accordance with the specification.
bool FindConstraint(const MediaConstraintsInterface* constraints,
const std::string& key, bool* value,
size_t* mandatory_constraints) {
std::string string_value;
if (!constraints) {
return false;
}
if (constraints->GetMandatory().FindFirst(key, &string_value)) {
if (mandatory_constraints) {
++*mandatory_constraints;
}
return rtc::FromString(string_value, value);
}
if (constraints->GetOptional().FindFirst(key, &string_value)) {
return rtc::FromString(string_value, value);
}
return false;
return ::FindConstraint<bool>(constraints, key, value, mandatory_constraints);
}
// As above, but for integers.
bool FindConstraint(const MediaConstraintsInterface* constraints,
const std::string& key,
int* value,
size_t* mandatory_constraints) {
std::string string_value;
if (!constraints) {
return false;
}
if (constraints->GetMandatory().FindFirst(key, &string_value)) {
if (mandatory_constraints) {
++*mandatory_constraints;
}
return rtc::FromString(string_value, value);
}
if (constraints->GetOptional().FindFirst(key, &string_value)) {
return rtc::FromString(string_value, value);
}
return false;
}
void ConstraintToOptionalBool(const MediaConstraintsInterface* constraints,
const std::string& key,
rtc::Optional<bool>* value_out) {
bool value;
bool present = FindConstraint(constraints, key, &value, nullptr);
if (present) {
*value_out = rtc::Optional<bool>(value);
}
}
void ConstraintToOptionalInt(const MediaConstraintsInterface* constraints,
const std::string& key,
rtc::Optional<int>* value_out) {
int value;
bool present = FindConstraint(constraints, key, &value, nullptr);
if (present) {
*value_out = rtc::Optional<int>(value);
}
return ::FindConstraint<int>(constraints, key, value, mandatory_constraints);
}
void CopyConstraintsIntoRtcConfiguration(
@ -203,15 +205,71 @@ void CopyConstraintsIntoRtcConfiguration(
MediaConstraintsInterface::kEnableVideoSuspendBelowMinBitrate,
&configuration->media_config.video.suspend_below_min_bitrate,
nullptr);
ConstraintToOptionalInt(constraints,
ConstraintToOptional<int>(constraints,
MediaConstraintsInterface::kScreencastMinBitrate,
&configuration->screencast_min_bitrate);
ConstraintToOptionalBool(constraints,
ConstraintToOptional<bool>(constraints,
MediaConstraintsInterface::kCombinedAudioVideoBwe,
&configuration->combined_audio_video_bwe);
ConstraintToOptionalBool(constraints,
ConstraintToOptional<bool>(constraints,
MediaConstraintsInterface::kEnableDtlsSrtp,
&configuration->enable_dtls_srtp);
}
void CopyConstraintsIntoAudioOptions(
const MediaConstraintsInterface* constraints,
cricket::AudioOptions* options) {
if (!constraints) {
return;
}
ConstraintToOptional<bool>(constraints,
MediaConstraintsInterface::kGoogEchoCancellation,
&options->echo_cancellation);
ConstraintToOptional<bool>(
constraints, MediaConstraintsInterface::kExtendedFilterEchoCancellation,
&options->extended_filter_aec);
ConstraintToOptional<bool>(constraints,
MediaConstraintsInterface::kDAEchoCancellation,
&options->delay_agnostic_aec);
ConstraintToOptional<bool>(constraints,
MediaConstraintsInterface::kAutoGainControl,
&options->auto_gain_control);
ConstraintToOptional<bool>(
constraints, MediaConstraintsInterface::kExperimentalAutoGainControl,
&options->experimental_agc);
ConstraintToOptional<bool>(constraints,
MediaConstraintsInterface::kNoiseSuppression,
&options->noise_suppression);
ConstraintToOptional<bool>(
constraints, MediaConstraintsInterface::kExperimentalNoiseSuppression,
&options->experimental_ns);
ConstraintToOptional<bool>(
constraints, MediaConstraintsInterface::kIntelligibilityEnhancer,
&options->intelligibility_enhancer);
ConstraintToOptional<bool>(constraints,
MediaConstraintsInterface::kLevelControl,
&options->level_control);
ConstraintToOptional<bool>(constraints,
MediaConstraintsInterface::kHighpassFilter,
&options->highpass_filter);
ConstraintToOptional<bool>(constraints,
MediaConstraintsInterface::kTypingNoiseDetection,
&options->typing_detection);
ConstraintToOptional<bool>(constraints,
MediaConstraintsInterface::kAudioMirroring,
&options->stereo_swapping);
ConstraintToOptional<float>(
constraints, MediaConstraintsInterface::kLevelControlInitialPeakLevelDBFS,
&options->level_control_initial_peak_level_dbfs);
ConstraintToOptional<std::string>(
constraints, MediaConstraintsInterface::kAudioNetworkAdaptorConfig,
&options->audio_network_adaptor_config);
// When |kAudioNetworkAdaptorConfig| is defined, it both means that audio
// network adaptor is desired, and provides the config string.
if (options->audio_network_adaptor_config) {
options->audio_network_adaptor = rtc::Optional<bool>(true);
}
}
} // namespace webrtc

View File

@ -141,6 +141,11 @@ void CopyConstraintsIntoRtcConfiguration(
const MediaConstraintsInterface* constraints,
PeerConnectionInterface::RTCConfiguration* configuration);
// Copy all relevant constraints into an AudioOptions object.
void CopyConstraintsIntoAudioOptions(
const MediaConstraintsInterface* constraints,
cricket::AudioOptions* options);
} // namespace webrtc
#endif // WEBRTC_API_MEDIACONSTRAINTSINTERFACE_H_

View File

@ -776,6 +776,7 @@ class PeerConnectionFactoryInterface : public rtc::RefCountInterface {
virtual rtc::scoped_refptr<AudioSourceInterface> CreateAudioSource(
const cricket::AudioOptions& options) = 0;
// Deprecated - use version above.
// Can use CopyConstraintsIntoAudioOptions to bridge the gap.
virtual rtc::scoped_refptr<AudioSourceInterface> CreateAudioSource(
const MediaConstraintsInterface* constraints) = 0;

View File

@ -1442,8 +1442,10 @@ JOW(jlong, PeerConnectionFactory_nativeCreateAudioSource)(
new ConstraintsWrapper(jni, j_constraints));
rtc::scoped_refptr<PeerConnectionFactoryInterface> factory(
factoryFromJava(native_factory));
cricket::AudioOptions options;
CopyConstraintsIntoAudioOptions(constraints.get(), &options);
rtc::scoped_refptr<AudioSourceInterface> source(
factory->CreateAudioSource(constraints.get()));
factory->CreateAudioSource(options));
return (jlong)source.release();
}