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

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

Issue 2847673002: [Chromecast] Complete PostProcessingPipeline changes (Closed)
Patch Set: Fix deps Created 3 years, 8 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/filter_group.cc
diff --git a/chromecast/media/cma/backend/alsa/filter_group.cc b/chromecast/media/cma/backend/alsa/filter_group.cc
index e041b7e9b8ef6c6ea5a07d1985896d1cfbdab37a..2e798fe5327ec5df6f7d77030a5cc0cda38d770e 100644
--- a/chromecast/media/cma/backend/alsa/filter_group.cc
+++ b/chromecast/media/cma/backend/alsa/filter_group.cc
@@ -7,24 +7,27 @@
#include <algorithm>
#include "base/memory/ptr_util.h"
+#include "base/time/time.h"
#include "base/values.h"
#include "chromecast/media/cma/backend/alsa/post_processing_pipeline.h"
#include "media/base/audio_bus.h"
+#include "media/base/vector_math.h"
namespace chromecast {
namespace media {
-FilterGroup::FilterGroup(const std::unordered_set<std::string>& input_types,
- AudioContentType content_type,
- int num_channels,
- const base::ListValue* filter_list)
- : input_types_(input_types),
- content_type_(content_type),
- num_channels_(num_channels),
+FilterGroup::FilterGroup(int num_channels,
+ const std::string& name,
+ const base::ListValue* filter_list,
+ const std::unordered_set<std::string>& device_ids,
+ const std::vector<FilterGroup*>& mixed_inputs)
+ : num_channels_(num_channels),
+ name_(name),
+ device_ids_(device_ids),
+ mixed_inputs_(mixed_inputs),
output_samples_per_second_(0),
channels_(num_channels_),
post_processing_pipeline_(
- base::MakeUnique<PostProcessingPipeline>(filter_list,
- num_channels_)) {}
+ PostProcessingPipeline::Create(name_, filter_list, num_channels_)) {}
FilterGroup::~FilterGroup() = default;
@@ -34,27 +37,46 @@ void FilterGroup::Initialize(int output_samples_per_second) {
}
bool FilterGroup::CanProcessInput(StreamMixerAlsa::InputQueue* input) {
- return !(input_types_.find(input->device_id()) == input_types_.end());
+ return !(device_ids_.find(input->device_id()) == device_ids_.end());
}
void FilterGroup::AddActiveInput(StreamMixerAlsa::InputQueue* input) {
active_inputs_.push_back(input);
}
-std::vector<uint8_t>* FilterGroup::GetInterleaved() {
- return &interleaved_;
-}
-
-bool FilterGroup::MixAndFilter(int chunk_size) {
+float FilterGroup::MixAndFilter(int chunk_size) {
DCHECK_NE(output_samples_per_second_, 0);
- if (active_inputs_.empty() && !post_processing_pipeline_->IsRinging()) {
- return false; // Output will be silence, no need to mix.
- }
ResizeBuffersIfNecessary(chunk_size);
- mixed_->ZeroFramesPartial(0, chunk_size);
float volume = 0.0f;
+
+ // Recursively mix inputs.
+ for (auto* filter_group : mixed_inputs_) {
+ volume = std::max(volume, filter_group->MixAndFilter(chunk_size));
+ }
+
+ // |volume| can only be 0 if no |mixed_inputs_| have data.
+ // This is true because FilterGroup can only return 0 if:
+ // a) It has no data and its PostProcessorPipeline is not ringing.
+ // (early return, below) or
+ // b) The output volume is 0 and has NEVER been non-zero,
+ // since FilterGroup will use last_volume_ if volume is 0.
+ // In this case, there was never any data in the pipeline.
+ if (active_inputs_.empty() && volume == 0.0f &&
+ !post_processing_pipeline_->IsRinging()) {
+ if (frames_zeroed_ < chunk_size) {
+ // Ensure mixed_ is zeros. This is necessary if |mixed_| is read later.
+ mixed_->ZeroFramesPartial(0, chunk_size);
+ frames_zeroed_ = chunk_size;
+ }
+ return 0.0f; // Output will be silence, no need to mix.
+ }
+
+ frames_zeroed_ = 0;
+
+ // Mix InputQueues
+ mixed_->ZeroFramesPartial(0, chunk_size);
for (StreamMixerAlsa::InputQueue* input : active_inputs_) {
input->GetResampledData(temp_.get(), chunk_size);
for (int c = 0; c < num_channels_; ++c) {
@@ -65,18 +87,37 @@ bool FilterGroup::MixAndFilter(int chunk_size) {
volume = std::max(volume, input->EffectiveVolume());
}
- post_processing_pipeline_->ProcessFrames(channels_, chunk_size, volume,
- active_inputs_.empty());
- mixed_->ToInterleaved(chunk_size, BytesPerOutputFormatSample(),
- interleaved_.data());
- return true;
+ // Mix FilterGroups
+ for (FilterGroup* group : mixed_inputs_) {
+ if (group->last_volume() > 0.0f) {
+ for (int c = 0; c < num_channels_; ++c) {
+ ::media::vector_math::FMAC(group->data()->channel(c), 1.0f, chunk_size,
+ channels_[c]);
+ }
+ }
+ }
+
+ bool is_silence = (volume == 0.0f);
+
+ // Allow paused streams to "ring out" at the last valid volume.
+ // If the stream volume is actually 0, this doesn't matter, since the
+ // data is 0's anyway.
+ if (!is_silence) {
+ last_volume_ = volume;
+ }
+
+ delay_frames_ = post_processing_pipeline_->ProcessFrames(
+ channels_, chunk_size, last_volume_, is_silence);
+ return last_volume_;
}
-void FilterGroup::ClearInterleaved(int chunk_size) {
- ResizeBuffersIfNecessary(chunk_size);
- memset(interleaved_.data(), 0,
- static_cast<size_t>(chunk_size) * num_channels_ *
- BytesPerOutputFormatSample());
+int64_t FilterGroup::GetRenderingDelayMicroseconds() {
+ return delay_frames_ * base::Time::kMicrosecondsPerSecond /
+ output_samples_per_second_;
+}
+
+void FilterGroup::ClearActiveInputs() {
+ active_inputs_.clear();
}
void FilterGroup::ResizeBuffersIfNecessary(int chunk_size) {
@@ -89,26 +130,6 @@ void FilterGroup::ResizeBuffersIfNecessary(int chunk_size) {
if (!temp_ || temp_->frames() < chunk_size) {
temp_ = ::media::AudioBus::Create(num_channels_, chunk_size);
}
-
- size_t interleaved_size = static_cast<size_t>(chunk_size) * num_channels_ *
- BytesPerOutputFormatSample();
-
- if (interleaved_.size() < interleaved_size) {
- interleaved_.resize(interleaved_size);
- }
-}
-
-int FilterGroup::BytesPerOutputFormatSample() {
- return sizeof(int32_t);
-}
-
-void FilterGroup::ClearActiveInputs() {
- active_inputs_.clear();
-}
-
-void FilterGroup::DisablePostProcessingForTest() {
- post_processing_pipeline_ =
- base::MakeUnique<PostProcessingPipeline>(nullptr, num_channels_);
}
} // namespace media
« no previous file with comments | « chromecast/media/cma/backend/alsa/filter_group.h ('k') | chromecast/media/cma/backend/alsa/post_processing_pipeline.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698