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

Unified Diff: chromecast/media/cma/backend/alsa/stream_mixer_alsa.cc

Issue 2738873002: [Chromecast] Implement new volume control API (Closed)
Patch Set: no need for ALSA volume control Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chromecast/media/cma/backend/alsa/stream_mixer_alsa.cc
diff --git a/chromecast/media/cma/backend/alsa/stream_mixer_alsa.cc b/chromecast/media/cma/backend/alsa/stream_mixer_alsa.cc
index 0430d330b69ef74c5e9805ed227392c2ff70f111..8d9bfea14f44327a9f53cc77ae3237154695eaa4 100644
--- a/chromecast/media/cma/backend/alsa/stream_mixer_alsa.cc
+++ b/chromecast/media/cma/backend/alsa/stream_mixer_alsa.cc
@@ -17,7 +17,6 @@
#include "base/memory/weak_ptr.h"
#include "base/numerics/saturated_arithmetic.h"
#include "base/single_thread_task_runner.h"
-#include "base/strings/string_number_conversions.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chromecast/base/chromecast_switches.h"
@@ -126,50 +125,6 @@ int64_t TimespecToMicroseconds(struct timespec time) {
time.tv_nsec / 1000;
}
-bool GetSwitchValueAsInt(const std::string& switch_name,
- int default_value,
- int* value) {
- DCHECK(value);
- *value = default_value;
- if (!base::CommandLine::InitializedForCurrentProcess()) {
- LOG(WARNING) << "No CommandLine for current process.";
- return false;
- }
- const base::CommandLine* command_line =
- base::CommandLine::ForCurrentProcess();
- if (!command_line->HasSwitch(switch_name)) {
- return false;
- }
-
- int arg_value;
- if (!base::StringToInt(command_line->GetSwitchValueASCII(switch_name),
- &arg_value)) {
- LOG(DFATAL) << "--" << switch_name << " only accepts integers as arguments";
- return false;
- }
- *value = arg_value;
- return true;
-}
-
-bool GetSwitchValueAsNonNegativeInt(const std::string& switch_name,
- int default_value,
- int* value) {
- DCHECK_GE(default_value, 0) << "--" << switch_name
- << " must have a non-negative default value";
- DCHECK(value);
-
- if (!GetSwitchValueAsInt(switch_name, default_value, value)) {
- return false;
- }
-
- if (*value < 0) {
- LOG(DFATAL) << "--" << switch_name << " must have a non-negative value";
- *value = default_value;
- return false;
- }
- return true;
-}
-
void VectorAccumulate(const int32_t* source, size_t size, int32_t* dest) {
for (size_t i = 0; i < size; ++i) {
dest[i] = base::SaturatedAddition(source[i], dest[i]);
@@ -214,7 +169,6 @@ StreamMixerAlsa::StreamMixerAlsa()
pcm_status_(nullptr),
pcm_format_(SND_PCM_FORMAT_UNKNOWN),
alsa_buffer_size_(0),
- alsa_period_explicitly_set(false),
alsa_period_size_(0),
alsa_start_threshold_(0),
alsa_avail_min_(0),
@@ -222,6 +176,13 @@ StreamMixerAlsa::StreamMixerAlsa()
retry_write_frames_timer_(new base::Timer(false, false)),
check_close_timeout_(kDefaultCheckCloseTimeoutMs),
check_close_timer_(new base::Timer(false, false)) {
+ for (auto type : {AudioContentType::kMedia, AudioContentType::kAlarm,
slan 2017/03/13 22:09:51 Perhaps we should use a static assert in here to m
kmackay 2017/03/14 00:20:59 Done.
+ AudioContentType::kCommunication}) {
+ volume_[type] = 1.0f;
+ volume_limit_[type] = 1.0f;
+ muted_[type] = false;
+ }
+
if (single_threaded_for_test_) {
mixer_task_runner_ = base::ThreadTaskRunnerHandle::Get();
} else {
@@ -240,9 +201,8 @@ StreamMixerAlsa::StreamMixerAlsa()
switches::kAlsaOutputDevice);
}
- int fixed_samples_per_second;
- GetSwitchValueAsNonNegativeInt(switches::kAlsaFixedOutputSampleRate,
- kInvalidSampleRate, &fixed_samples_per_second);
+ int fixed_samples_per_second = GetSwitchValueNonNegativeInt(
+ switches::kAlsaFixedOutputSampleRate, kInvalidSampleRate);
if (fixed_samples_per_second != kInvalidSampleRate) {
LOG(INFO) << "Setting fixed sample rate to " << fixed_samples_per_second;
}
@@ -259,18 +219,19 @@ StreamMixerAlsa::StreamMixerAlsa()
filter_groups_.push_back(base::MakeUnique<FilterGroup>(
std::unordered_set<std::string>(
{::media::AudioDeviceDescription::kCommunicationsDeviceId}),
- AudioFilterFactory::COMMUNICATION_AUDIO_FILTER));
+ AudioFilterFactory::COMMUNICATION_AUDIO_FILTER,
+ AudioContentType::kMedia));
filter_groups_.push_back(base::MakeUnique<FilterGroup>(
std::unordered_set<std::string>({kAlarmAudioDeviceId}),
- AudioFilterFactory::ALARM_AUDIO_FILTER));
+ AudioFilterFactory::ALARM_AUDIO_FILTER, AudioContentType::kAlarm));
filter_groups_.push_back(base::MakeUnique<FilterGroup>(
std::unordered_set<std::string>({kTtsAudioDeviceId}),
- AudioFilterFactory::TTS_AUDIO_FILTER));
+ AudioFilterFactory::TTS_AUDIO_FILTER, AudioContentType::kCommunication));
filter_groups_.push_back(base::MakeUnique<FilterGroup>(
std::unordered_set<std::string>(
{::media::AudioDeviceDescription::kDefaultDeviceId,
kLocalAudioDeviceId, ""}),
- AudioFilterFactory::MEDIA_AUDIO_FILTER));
+ AudioFilterFactory::MEDIA_AUDIO_FILTER, AudioContentType::kMedia));
DefineAlsaParameters();
}
@@ -281,52 +242,42 @@ void StreamMixerAlsa::ResetTaskRunnerForTest() {
void StreamMixerAlsa::DefineAlsaParameters() {
// Get the ALSA output configuration from the command line.
- int buffer_size;
- GetSwitchValueAsNonNegativeInt(switches::kAlsaOutputBufferSize,
- kDefaultOutputBufferSizeFrames, &buffer_size);
- alsa_buffer_size_ = buffer_size;
-
- int period_size;
- if (GetSwitchValueAsNonNegativeInt(switches::kAlsaOutputPeriodSize,
- alsa_buffer_size_ / 16, &period_size)) {
- if (period_size >= buffer_size) {
- LOG(DFATAL) << "ALSA period size must be smaller than the buffer size";
- period_size = buffer_size / 2;
- } else {
- alsa_period_explicitly_set = true;
- }
+ alsa_buffer_size_ = GetSwitchValueNonNegativeInt(
+ switches::kAlsaOutputBufferSize, kDefaultOutputBufferSizeFrames);
+
+ alsa_period_size_ = GetSwitchValueNonNegativeInt(
+ switches::kAlsaOutputPeriodSize, alsa_buffer_size_ / 16);
+ if (alsa_period_size_ >= alsa_buffer_size_) {
+ LOG(DFATAL) << "ALSA period size must be smaller than the buffer size";
+ alsa_period_size_ = alsa_buffer_size_ / 2;
}
- alsa_period_size_ = period_size;
- int start_threshold;
- GetSwitchValueAsNonNegativeInt(switches::kAlsaOutputStartThreshold,
- (buffer_size / period_size) * period_size,
- &start_threshold);
- if (start_threshold > buffer_size) {
+ alsa_start_threshold_ = GetSwitchValueNonNegativeInt(
+ switches::kAlsaOutputStartThreshold,
+ (alsa_buffer_size_ / alsa_period_size_) * alsa_period_size_);
+ if (alsa_start_threshold_ > alsa_buffer_size_) {
LOG(DFATAL) << "ALSA start threshold must be no larger than "
<< "the buffer size";
- start_threshold = (buffer_size / period_size) * period_size;
+ alsa_start_threshold_ =
+ (alsa_buffer_size_ / alsa_period_size_) * alsa_period_size_;
}
- alsa_start_threshold_ = start_threshold;
// By default, allow the transfer when at least period_size samples can be
// processed.
- int avail_min;
- GetSwitchValueAsNonNegativeInt(switches::kAlsaOutputAvailMin, period_size,
- &avail_min);
- if (avail_min > buffer_size) {
+ alsa_avail_min_ = GetSwitchValueNonNegativeInt(switches::kAlsaOutputAvailMin,
+ alsa_period_size_);
+ if (alsa_avail_min_ > alsa_buffer_size_) {
LOG(DFATAL) << "ALSA avail min must be no larger than the buffer size";
- avail_min = alsa_period_size_;
+ alsa_avail_min_ = alsa_period_size_;
}
- alsa_avail_min_ = avail_min;
// --accept-resource-provider should imply a check close timeout of 0.
int default_close_timeout = chromecast::GetSwitchValueBoolean(
switches::kAcceptResourceProvider, false)
? 0
: kDefaultCheckCloseTimeoutMs;
- GetSwitchValueAsInt(switches::kAlsaCheckCloseTimeout, default_close_timeout,
- &check_close_timeout_);
+ check_close_timeout_ = GetSwitchValueInt(switches::kAlsaCheckCloseTimeout,
+ default_close_timeout);
}
unsigned int StreamMixerAlsa::DetermineOutputRate(unsigned int requested_rate) {
@@ -442,11 +393,7 @@ int StreamMixerAlsa::SetAlsaPlaybackParams() {
<< " frames). This may lead to an increase in "
"either audio latency or audio underruns.";
- // Always try to use the value for period_size that was passed in on the
- // command line, if any.
- if (!alsa_period_explicitly_set) {
- alsa_period_size_ = alsa_buffer_size_ / 16;
- } else if (alsa_period_size_ >= alsa_buffer_size_) {
+ if (alsa_period_size_ >= alsa_buffer_size_) {
snd_pcm_uframes_t new_period_size = alsa_buffer_size_ / 2;
LOG(DFATAL) << "Configured period size (" << alsa_period_size_
<< ") is >= actual buffer size (" << alsa_buffer_size_
@@ -660,6 +607,14 @@ void StreamMixerAlsa::AddInput(std::unique_ptr<InputQueue> input) {
CheckChangeOutputRate(input->input_samples_per_second());
}
+ auto type = input->content_type();
+ if (input->primary()) {
+ input->SetContentTypeVolume(std::min(volume_limit_[type], volume_[type]));
+ } else {
+ input->SetContentTypeVolume(volume_[type]);
+ }
+ input->SetMuted(muted_[type]);
+
check_close_timer_->Stop();
switch (state_) {
case kStateUninitialized:
@@ -967,5 +922,57 @@ void StreamMixerAlsa::RemoveLoopbackAudioObserver(
observer->OnRemoved();
}
+void StreamMixerAlsa::SetVolume(AudioContentType type, float level) {
+ RUN_ON_MIXER_THREAD(&StreamMixerAlsa::SetVolume, type, level);
+ volume_[type] = level;
+ float effective_volume = std::min(volume_limit_[type], level);
slan 2017/03/13 22:09:51 Regarding my earlier comment about using a VolumeC
kmackay 2017/03/14 00:20:59 Done.
+ for (auto&& input : inputs_) {
+ if (input->content_type() == type) {
+ if (input->primary()) {
+ input->SetContentTypeVolume(effective_volume);
+ } else {
+ // Volume limits don't apply to effects streams.
+ input->SetContentTypeVolume(level);
+ }
+ }
+ }
+
+ for (auto&& filter : filter_groups_) {
+ if (filter->content_type() == type) {
+ filter->set_volume(effective_volume);
+ }
+ }
+}
+
+void StreamMixerAlsa::SetMuted(AudioContentType type, bool muted) {
+ RUN_ON_MIXER_THREAD(&StreamMixerAlsa::SetMuted, type, muted);
+ muted_[type] = muted;
+ for (auto&& input : inputs_) {
+ if (input->content_type() == type) {
+ input->SetMuted(muted);
+ }
+ }
+}
+
+void StreamMixerAlsa::SetOutputLimit(AudioContentType type, float limit) {
+ RUN_ON_MIXER_THREAD(&StreamMixerAlsa::SetOutputLimit, type, limit);
+ LOG(INFO) << "Set volume limit for " << static_cast<int>(type) << " to "
+ << limit;
+ volume_limit_[type] = limit;
+ float effective_volume = std::min(volume_[type], limit);
+ for (auto&& input : inputs_) {
+ // Volume limits don't apply to effects streams.
+ if (input->primary() && input->content_type() == type) {
+ input->SetContentTypeVolume(effective_volume);
+ }
+ }
+
+ for (auto&& filter : filter_groups_) {
+ if (filter->content_type() == type) {
+ filter->set_volume(effective_volume);
+ }
+ }
+}
+
} // namespace media
} // namespace chromecast

Powered by Google App Engine
This is Rietveld 408576698