Commit 6cdff69d authored by Sergey Ulanov's avatar Sergey Ulanov Committed by Commit Bot

[chromecast] Add --audio-output-sample-rate for Fuchsia

It is possible to set fixed sample rate in cast_shell on Linux with
--alsa-fixed-output-sample-rate, but it wasn't possible on Fuchsia.
Added --audio-output-sample-rate, which allows to set fixed sample rate
on both platforms. For backward compatibility kept the old ALSA-specific
flag, but it's marked as deprecated now.

Bug: 772488
Change-Id: I0f980f09b432768ff9bb51191a9b1ec31e89274f
Reviewed-on: https://chromium-review.googlesource.com/798066Reviewed-by: default avatarLuke Halliwell <halliwell@chromium.org>
Reviewed-by: default avatarKenneth MacKay <kmackay@chromium.org>
Commit-Queue: Sergey Ulanov <sergeyu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#521050}
parent 6c1b6aa9
...@@ -69,6 +69,7 @@ const char kAlsaCheckCloseTimeout[] = "alsa-check-close-timeout"; ...@@ -69,6 +69,7 @@ const char kAlsaCheckCloseTimeout[] = "alsa-check-close-timeout";
const char kAlsaEnableUpsampling[] = "alsa-enable-upsampling"; const char kAlsaEnableUpsampling[] = "alsa-enable-upsampling";
// Optional flag to set a fixed sample rate for the alsa device. // Optional flag to set a fixed sample rate for the alsa device.
// Deprecated: Use --audio-output-sample-rate instead.
const char kAlsaFixedOutputSampleRate[] = "alsa-fixed-output-sample-rate"; const char kAlsaFixedOutputSampleRate[] = "alsa-fixed-output-sample-rate";
// Name of the simple mixer control element that the ALSA-based media library // Name of the simple mixer control element that the ALSA-based media library
...@@ -96,6 +97,11 @@ const char kMaxOutputVolumeDba1m[] = "max-output-volume-dba1m"; ...@@ -96,6 +97,11 @@ const char kMaxOutputVolumeDba1m[] = "max-output-volume-dba1m";
// value is 2. // value is 2.
const char kAudioOutputChannels[] = "audio-output-channels"; const char kAudioOutputChannels[] = "audio-output-channels";
// Specify fixed sample rate for audio output stream. If this flag is not
// specified the StreamMixer will choose sample rate based on the sample rate of
// the media stream.
const char kAudioOutputSampleRate[] = "audio-output-sample-rate";
// Some platforms typically have very little 'free' memory, but plenty is // Some platforms typically have very little 'free' memory, but plenty is
// available in buffers+cached. For such platforms, configure this amount // available in buffers+cached. For such platforms, configure this amount
// as the portion of buffers+cached memory that should be treated as // as the portion of buffers+cached memory that should be treated as
......
...@@ -38,6 +38,9 @@ extern const char kPreviousApp[]; ...@@ -38,6 +38,9 @@ extern const char kPreviousApp[];
extern const char kAcceptResourceProvider[]; extern const char kAcceptResourceProvider[];
// ALSA-based CMA switches. (Only valid for audio products.) // ALSA-based CMA switches. (Only valid for audio products.)
// TODO(sergeyu): kAlsaEnableUpsampling and kAlsaCheckCloseTimeout are
// implemented in StreamMixer, which is not ALSA-specific - it's also used on
// Fuchsia. Rename these flags.
extern const char kAlsaOutputBufferSize[]; extern const char kAlsaOutputBufferSize[];
extern const char kAlsaOutputPeriodSize[]; extern const char kAlsaOutputPeriodSize[];
extern const char kAlsaOutputStartThreshold[]; extern const char kAlsaOutputStartThreshold[];
...@@ -51,6 +54,7 @@ extern const char kAlsaMuteDeviceName[]; ...@@ -51,6 +54,7 @@ extern const char kAlsaMuteDeviceName[];
extern const char kAlsaMuteElementName[]; extern const char kAlsaMuteElementName[];
extern const char kMaxOutputVolumeDba1m[]; extern const char kMaxOutputVolumeDba1m[];
extern const char kAudioOutputChannels[]; extern const char kAudioOutputChannels[];
extern const char kAudioOutputSampleRate[];
// Memory pressure switches // Memory pressure switches
extern const char kMemPressureSystemReservedKb[]; extern const char kMemPressureSystemReservedKb[];
......
...@@ -143,10 +143,6 @@ void MixerOutputStreamAlsa::SetAlsaWrapperForTest( ...@@ -143,10 +143,6 @@ void MixerOutputStreamAlsa::SetAlsaWrapperForTest(
alsa_ = std::move(alsa); alsa_ = std::move(alsa);
} }
bool MixerOutputStreamAlsa::IsFixedSampleRate() {
return fixed_sample_rate_ != kInvalidSampleRate;
}
bool MixerOutputStreamAlsa::Start(int sample_rate, int channels) { bool MixerOutputStreamAlsa::Start(int sample_rate, int channels) {
if (!alsa_) { if (!alsa_) {
alsa_ = std::make_unique<AlsaWrapper>(); alsa_ = std::make_unique<AlsaWrapper>();
...@@ -427,22 +423,9 @@ void MixerOutputStreamAlsa::DefineAlsaParameters() { ...@@ -427,22 +423,9 @@ void MixerOutputStreamAlsa::DefineAlsaParameters() {
LOG(DFATAL) << "ALSA avail min must be no larger than the buffer size"; LOG(DFATAL) << "ALSA avail min must be no larger than the buffer size";
alsa_avail_min_ = alsa_period_size_; alsa_avail_min_ = alsa_period_size_;
} }
fixed_sample_rate_ = GetSwitchValueNonNegativeInt(
switches::kAlsaFixedOutputSampleRate, kInvalidSampleRate);
if (fixed_sample_rate_ != kInvalidSampleRate) {
LOG(INFO) << "Setting fixed sample rate to " << fixed_sample_rate_;
}
} }
int MixerOutputStreamAlsa::DetermineOutputRate(int requested_sample_rate) { int MixerOutputStreamAlsa::DetermineOutputRate(int requested_sample_rate) {
if (fixed_sample_rate_ != kInvalidSampleRate) {
LOG(INFO) << "Requested output rate is " << requested_sample_rate;
LOG(INFO) << "Cannot change rate since it is fixed to "
<< fixed_sample_rate_;
return fixed_sample_rate_;
}
unsigned int unsigned_output_sample_rate = requested_sample_rate; unsigned int unsigned_output_sample_rate = requested_sample_rate;
// Try the requested sample rate. If the ALSA driver doesn't know how to deal // Try the requested sample rate. If the ALSA driver doesn't know how to deal
......
...@@ -27,7 +27,6 @@ class MixerOutputStreamAlsa : public MixerOutputStream { ...@@ -27,7 +27,6 @@ class MixerOutputStreamAlsa : public MixerOutputStream {
void SetAlsaWrapperForTest(std::unique_ptr<AlsaWrapper> alsa); void SetAlsaWrapperForTest(std::unique_ptr<AlsaWrapper> alsa);
// MixerOutputStream interface. // MixerOutputStream interface.
bool IsFixedSampleRate() override;
bool Start(int requested_sample_rate, int channels) override; bool Start(int requested_sample_rate, int channels) override;
bool GetTimeUntilUnderrun(base::TimeDelta* result) override; bool GetTimeUntilUnderrun(base::TimeDelta* result) override;
int GetSampleRate() override; int GetSampleRate() override;
...@@ -57,9 +56,6 @@ class MixerOutputStreamAlsa : public MixerOutputStream { ...@@ -57,9 +56,6 @@ class MixerOutputStreamAlsa : public MixerOutputStream {
void UpdateRenderingDelay(int newly_pushed_frames); void UpdateRenderingDelay(int newly_pushed_frames);
// Value of --alsa-fixed-output-sample-rate flag if any.
int fixed_sample_rate_ = kInvalidSampleRate;
std::unique_ptr<AlsaWrapper> alsa_; std::unique_ptr<AlsaWrapper> alsa_;
snd_pcm_t* pcm_ = nullptr; snd_pcm_t* pcm_ = nullptr;
......
...@@ -39,10 +39,6 @@ MixerOutputStreamFuchsia::~MixerOutputStreamFuchsia() { ...@@ -39,10 +39,6 @@ MixerOutputStreamFuchsia::~MixerOutputStreamFuchsia() {
fuchsia_audio_manager_free(manager_); fuchsia_audio_manager_free(manager_);
} }
bool MixerOutputStreamFuchsia::IsFixedSampleRate() {
return false;
}
bool MixerOutputStreamFuchsia::Start(int requested_sample_rate, int channels) { bool MixerOutputStreamFuchsia::Start(int requested_sample_rate, int channels) {
DCHECK(!stream_); DCHECK(!stream_);
......
...@@ -21,7 +21,6 @@ class MixerOutputStreamFuchsia : public MixerOutputStream { ...@@ -21,7 +21,6 @@ class MixerOutputStreamFuchsia : public MixerOutputStream {
~MixerOutputStreamFuchsia() override; ~MixerOutputStreamFuchsia() override;
// MixerOutputStream interface. // MixerOutputStream interface.
bool IsFixedSampleRate() override;
bool Start(int requested_sample_rate, int channels) override; bool Start(int requested_sample_rate, int channels) override;
bool GetTimeUntilUnderrun(base::TimeDelta* result) override; bool GetTimeUntilUnderrun(base::TimeDelta* result) override;
int GetSampleRate() override; int GetSampleRate() override;
......
...@@ -26,9 +26,6 @@ class MixerOutputStream { ...@@ -26,9 +26,6 @@ class MixerOutputStream {
virtual ~MixerOutputStream() {} virtual ~MixerOutputStream() {}
// Returns true if the sample rate is fixed.
virtual bool IsFixedSampleRate() = 0;
// Start the stream. Caller must call GetSampleRate() to get the actual sample // Start the stream. Caller must call GetSampleRate() to get the actual sample
// rate selected for the stream. It may be different from // rate selected for the stream. It may be different from
// |requested_sample_rate|, e.g. if IsFixedSampleRate() is true, or the device // |requested_sample_rate|, e.g. if IsFixedSampleRate() is true, or the device
......
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
#include <utility> #include <utility>
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/lazy_instance.h" #include "base/lazy_instance.h"
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
...@@ -152,13 +151,27 @@ StreamMixer::StreamMixer() ...@@ -152,13 +151,27 @@ StreamMixer::StreamMixer()
num_output_channels_ == 1); num_output_channels_ == 1);
low_sample_rate_cutoff_ = low_sample_rate_cutoff_ =
chromecast::GetSwitchValueBoolean(switches::kAlsaEnableUpsampling, false) GetSwitchValueBoolean(switches::kAlsaEnableUpsampling, false)
? kLowSampleRateCutoff ? kLowSampleRateCutoff
: MixerOutputStream::kInvalidSampleRate; : MixerOutputStream::kInvalidSampleRate;
// Read post-processing configuration file fixed_sample_rate_ = GetSwitchValueNonNegativeInt(
PostProcessingPipelineParser pipeline_parser; switches::kAudioOutputSampleRate, MixerOutputStream::kInvalidSampleRate);
#if defined(USE_ALSA)
if (fixed_sample_rate_ == MixerOutputStream::kInvalidSampleRate) {
fixed_sample_rate_ =
GetSwitchValueNonNegativeInt(switches::kAlsaFixedOutputSampleRate,
MixerOutputStream::kInvalidSampleRate);
}
#endif // defined(USE_ALSA)
if (fixed_sample_rate_ != MixerOutputStream::kInvalidSampleRate) {
LOG(INFO) << "Setting fixed sample rate to " << fixed_sample_rate_;
}
// Read post-processing configuration file.
PostProcessingPipelineParser pipeline_parser;
CreatePostProcessors(&pipeline_parser); CreatePostProcessors(&pipeline_parser);
// TODO(jyw): command line flag for filter frame alignment. // TODO(jyw): command line flag for filter frame alignment.
...@@ -166,10 +179,10 @@ StreamMixer::StreamMixer() ...@@ -166,10 +179,10 @@ StreamMixer::StreamMixer()
<< "Alignment must be a power of 2."; << "Alignment must be a power of 2.";
// --accept-resource-provider should imply a check close timeout of 0. // --accept-resource-provider should imply a check close timeout of 0.
int default_close_timeout = chromecast::GetSwitchValueBoolean( int default_close_timeout =
switches::kAcceptResourceProvider, false) GetSwitchValueBoolean(switches::kAcceptResourceProvider, false)
? 0 ? 0
: kDefaultCheckCloseTimeoutMs; : kDefaultCheckCloseTimeoutMs;
check_close_timeout_ = GetSwitchValueInt(switches::kAlsaCheckCloseTimeout, check_close_timeout_ = GetSwitchValueInt(switches::kAlsaCheckCloseTimeout,
default_close_timeout); default_close_timeout);
} }
...@@ -275,17 +288,20 @@ void StreamMixer::FinishFinalize() { ...@@ -275,17 +288,20 @@ void StreamMixer::FinishFinalize() {
bool StreamMixer::Start() { bool StreamMixer::Start() {
DCHECK(mixer_task_runner_->BelongsToCurrentThread()); DCHECK(mixer_task_runner_->BelongsToCurrentThread());
int requested_sample_rate = requested_output_samples_per_second_;
if (!output_) if (!output_)
output_ = MixerOutputStream::Create(); output_ = MixerOutputStream::Create();
if (low_sample_rate_cutoff_ != MixerOutputStream::kInvalidSampleRate && int requested_sample_rate;
requested_sample_rate < low_sample_rate_cutoff_) { if (fixed_sample_rate_ != MixerOutputStream::kInvalidSampleRate) {
requested_sample_rate = fixed_sample_rate_;
} else if (low_sample_rate_cutoff_ != MixerOutputStream::kInvalidSampleRate &&
requested_output_samples_per_second_ < low_sample_rate_cutoff_) {
requested_sample_rate = requested_sample_rate =
output_samples_per_second_ != MixerOutputStream::kInvalidSampleRate output_samples_per_second_ != MixerOutputStream::kInvalidSampleRate
? output_samples_per_second_ ? output_samples_per_second_
: kLowSampleRateFallback; : kLowSampleRateFallback;
} else {
requested_sample_rate = requested_output_samples_per_second_;
} }
if (!output_->Start(requested_sample_rate, num_output_channels_)) { if (!output_->Start(requested_sample_rate, num_output_channels_)) {
...@@ -357,7 +373,8 @@ void StreamMixer::AddInput(std::unique_ptr<InputQueue> input) { ...@@ -357,7 +373,8 @@ void StreamMixer::AddInput(std::unique_ptr<InputQueue> input) {
// If the new input is a primary one, we may need to change the output // If the new input is a primary one, we may need to change the output
// sample rate to match its input sample rate. // sample rate to match its input sample rate.
// We only change the output rate if it is not set to a fixed value. // We only change the output rate if it is not set to a fixed value.
if (input->primary() && output_ && !output_->IsFixedSampleRate()) { if (input->primary() && output_ &&
fixed_sample_rate_ != MixerOutputStream::kInvalidSampleRate) {
CheckChangeOutputRate(input->input_samples_per_second()); CheckChangeOutputRate(input->input_samples_per_second());
} }
......
...@@ -281,6 +281,7 @@ class StreamMixer { ...@@ -281,6 +281,7 @@ class StreamMixer {
int requested_output_samples_per_second_ = 0; int requested_output_samples_per_second_ = 0;
int output_samples_per_second_ = 0; int output_samples_per_second_ = 0;
int low_sample_rate_cutoff_ = 0; int low_sample_rate_cutoff_ = 0;
int fixed_sample_rate_ = 0;
State state_; State state_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment