Commit db6b1c38 authored by Ken MacKay's avatar Ken MacKay Committed by Commit Bot

[Chromecast] Support mono input in mixer

Bug: internal b/77586397

Change-Id: I1a40b631bc3666e38008a367458737a4564f93a7
Reviewed-on: https://chromium-review.googlesource.com/994135Reviewed-by: default avatarStephen Lanham <slan@chromium.org>
Commit-Queue: Kenneth MacKay <kmackay@chromium.org>
Cr-Commit-Position: refs/heads/master@{#548224}
parent 5f93b7ae
...@@ -15,8 +15,6 @@ namespace media { ...@@ -15,8 +15,6 @@ namespace media {
namespace { namespace {
const int kNumOutputChannels = 2;
std::string AudioContentTypeToString(media::AudioContentType type) { std::string AudioContentTypeToString(media::AudioContentType type) {
switch (type) { switch (type) {
case media::AudioContentType::kAlarm: case media::AudioContentType::kAlarm:
...@@ -34,11 +32,9 @@ std::string AudioContentTypeToString(media::AudioContentType type) { ...@@ -34,11 +32,9 @@ std::string AudioContentTypeToString(media::AudioContentType type) {
DirectAudioSourceToken* CastMediaShlib::AddDirectAudioSource( DirectAudioSourceToken* CastMediaShlib::AddDirectAudioSource(
DirectAudioSource* source, DirectAudioSource* source,
const MediaPipelineDeviceParams& params, const MediaPipelineDeviceParams& params,
int source_sample_rate,
int playout_channel) { int playout_channel) {
DCHECK(source); DCHECK(source);
return new DirectMixerSource(source, params, source_sample_rate, return new DirectMixerSource(source, params, playout_channel);
playout_channel);
} }
// static // static
...@@ -49,11 +45,10 @@ void CastMediaShlib::RemoveDirectAudioSource(DirectAudioSourceToken* token) { ...@@ -49,11 +45,10 @@ void CastMediaShlib::RemoveDirectAudioSource(DirectAudioSourceToken* token) {
DirectMixerSource::DirectMixerSource(DirectAudioSource* direct_source, DirectMixerSource::DirectMixerSource(DirectAudioSource* direct_source,
const MediaPipelineDeviceParams& params, const MediaPipelineDeviceParams& params,
int source_sample_rate,
int playout_channel) int playout_channel)
: source_(direct_source), : source_(direct_source),
num_channels_(kNumOutputChannels), num_channels_(source_->GetNumChannels()),
input_samples_per_second_(source_sample_rate), input_samples_per_second_(source_->GetSampleRate()),
primary_(params.audio_type != primary_(params.audio_type !=
MediaPipelineDeviceParams::kAudioStreamSoundEffects), MediaPipelineDeviceParams::kAudioStreamSoundEffects),
device_id_(params.device_id), device_id_(params.device_id),
...@@ -61,7 +56,6 @@ DirectMixerSource::DirectMixerSource(DirectAudioSource* direct_source, ...@@ -61,7 +56,6 @@ DirectMixerSource::DirectMixerSource(DirectAudioSource* direct_source,
playout_channel_(playout_channel), playout_channel_(playout_channel),
mixer_(StreamMixer::Get()), mixer_(StreamMixer::Get()),
channel_vector_(num_channels_) { channel_vector_(num_channels_) {
DCHECK(source_);
LOG(INFO) << "Create " << device_id_ << " (" << this LOG(INFO) << "Create " << device_id_ << " (" << this
<< "), content type = " << AudioContentTypeToString(content_type_); << "), content type = " << AudioContentTypeToString(content_type_);
DCHECK(source_); DCHECK(source_);
......
...@@ -35,7 +35,6 @@ class DirectMixerSource : public MixerInput::Source, ...@@ -35,7 +35,6 @@ class DirectMixerSource : public MixerInput::Source,
DirectMixerSource(DirectAudioSource* direct_source, DirectMixerSource(DirectAudioSource* direct_source,
const MediaPipelineDeviceParams& params, const MediaPipelineDeviceParams& params,
int source_sample_rate,
int playout_channel); int playout_channel);
// Sets the volume multiplier for this stream. If |multiplier| < 0, sets the // Sets the volume multiplier for this stream. If |multiplier| < 0, sets the
......
...@@ -62,6 +62,9 @@ bool FilterGroup::CanProcessInput(const std::string& input_device_id) { ...@@ -62,6 +62,9 @@ bool FilterGroup::CanProcessInput(const std::string& input_device_id) {
void FilterGroup::AddInput(MixerInput* input) { void FilterGroup::AddInput(MixerInput* input) {
active_inputs_.insert(input); active_inputs_.insert(input);
if (mixed_) {
AddTempBuffer(input->num_channels(), mixed_->frames());
}
} }
void FilterGroup::RemoveInput(MixerInput* input) { void FilterGroup::RemoveInput(MixerInput* input) {
...@@ -114,10 +117,18 @@ float FilterGroup::MixAndFilter( ...@@ -114,10 +117,18 @@ float FilterGroup::MixAndFilter(
// Mix InputQueues // Mix InputQueues
mixed_->ZeroFramesPartial(0, num_frames); mixed_->ZeroFramesPartial(0, num_frames);
for (MixerInput* input : active_inputs_) { for (MixerInput* input : active_inputs_) {
int filled = input->FillAudioData(num_frames, rendering_delay, temp_.get()); DCHECK_LT(input->num_channels(), static_cast<int>(temp_buffers_.size()));
for (int c = 0; c < num_channels_; ++c) { DCHECK(temp_buffers_[input->num_channels()]);
input->VolumeScaleAccumulate(c != 0, temp_->channel(c), filled, ::media::AudioBus* temp = temp_buffers_[input->num_channels()].get();
mixed_->channel(c)); int filled = input->FillAudioData(num_frames, rendering_delay, temp);
int in_c = 0;
for (int out_c = 0; out_c < num_channels_; ++out_c) {
input->VolumeScaleAccumulate(out_c != 0, temp->channel(in_c), filled,
mixed_->channel(out_c));
++in_c;
if (in_c >= input->num_channels()) {
in_c = 0;
}
} }
volume = std::max(volume, input->InstantaneousVolume()); volume = std::max(volume, input->InstantaneousVolume());
content_type = std::max(content_type, input->content_type()); content_type = std::max(content_type, input->content_type());
...@@ -197,13 +208,26 @@ bool FilterGroup::ResizeBuffersIfNecessary(int num_frames) { ...@@ -197,13 +208,26 @@ bool FilterGroup::ResizeBuffersIfNecessary(int num_frames) {
return false; return false;
} }
mixed_ = ::media::AudioBus::Create(num_channels_, num_frames); mixed_ = ::media::AudioBus::Create(num_channels_, num_frames);
temp_ = ::media::AudioBus::Create(num_channels_, num_frames); temp_buffers_.clear();
for (MixerInput* input : active_inputs_) {
AddTempBuffer(input->num_channels(), num_frames);
}
interleaved_.reset(static_cast<float*>( interleaved_.reset(static_cast<float*>(
base::AlignedAlloc(num_frames * num_channels_ * sizeof(float), base::AlignedAlloc(num_frames * num_channels_ * sizeof(float),
::media::AudioBus::kChannelAlignment))); ::media::AudioBus::kChannelAlignment)));
return true; return true;
} }
void FilterGroup::AddTempBuffer(int num_channels, int num_frames) {
if (static_cast<int>(temp_buffers_.size()) <= num_channels) {
temp_buffers_.resize(num_channels + 1);
}
if (!temp_buffers_[num_channels]) {
temp_buffers_[num_channels] =
::media::AudioBus::Create(num_channels, num_frames);
}
}
void FilterGroup::SetPostProcessorConfig(const std::string& name, void FilterGroup::SetPostProcessorConfig(const std::string& name,
const std::string& config) { const std::string& config) {
post_processing_pipeline_->SetPostProcessorConfig(name, config); post_processing_pipeline_->SetPostProcessorConfig(name, config);
......
...@@ -120,6 +120,7 @@ class FilterGroup { ...@@ -120,6 +120,7 @@ class FilterGroup {
// Resizes temp_ and mixed_ if they are too small to hold |num_frames| frames. // Resizes temp_ and mixed_ if they are too small to hold |num_frames| frames.
// Returns |true| if |num_frames| is larger than all previous |num_frames|. // Returns |true| if |num_frames| is larger than all previous |num_frames|.
bool ResizeBuffersIfNecessary(int num_frames); bool ResizeBuffersIfNecessary(int num_frames);
void AddTempBuffer(int num_channels, int num_frames);
const int num_channels_; const int num_channels_;
const GroupType type_; const GroupType type_;
...@@ -139,7 +140,7 @@ class FilterGroup { ...@@ -139,7 +140,7 @@ class FilterGroup {
// Buffers that hold audio data while it is mixed. // Buffers that hold audio data while it is mixed.
// These are kept as members of this class to minimize copies and // These are kept as members of this class to minimize copies and
// allocations. // allocations.
std::unique_ptr<::media::AudioBus> temp_; std::vector<std::unique_ptr<::media::AudioBus>> temp_buffers_;
std::unique_ptr<::media::AudioBus> mixed_; std::unique_ptr<::media::AudioBus> mixed_;
// Interleaved data must be aligned to 16 bytes. // Interleaved data must be aligned to 16 bytes.
......
...@@ -145,7 +145,6 @@ class CHROMECAST_EXPORT CastMediaShlib { ...@@ -145,7 +145,6 @@ class CHROMECAST_EXPORT CastMediaShlib {
static DirectAudioSourceToken* AddDirectAudioSource( static DirectAudioSourceToken* AddDirectAudioSource(
DirectAudioSource* source, DirectAudioSource* source,
const MediaPipelineDeviceParams& params, const MediaPipelineDeviceParams& params,
int source_sample_rate,
int playout_channel) __attribute__((__weak__)); int playout_channel) __attribute__((__weak__));
// Removes a direct audio source, given the |token| that was returned by // Removes a direct audio source, given the |token| that was returned by
......
...@@ -21,6 +21,15 @@ class DirectAudioSource { ...@@ -21,6 +21,15 @@ class DirectAudioSource {
public: public:
using RenderingDelay = MediaPipelineBackend::AudioDecoder::RenderingDelay; using RenderingDelay = MediaPipelineBackend::AudioDecoder::RenderingDelay;
// Returns the sample rate of audio provided by the source, in samples per
// second.
virtual int GetSampleRate() = 0;
// Returns the number of audio channels provided by the source. This is the
// number of channels that will be requested when FillAudioPlaybackFrames()
// is called.
virtual int GetNumChannels() = 0;
// Returns the desired playback buffer size in frames. This is the desired // Returns the desired playback buffer size in frames. This is the desired
// value for |num_frames| when FillAudioPlaybackFrames(); it affects the // value for |num_frames| when FillAudioPlaybackFrames(); it affects the
// playback latency (larger value = higher latency). The backend may choose a // playback latency (larger value = higher latency). The backend may choose a
......
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