blob: b4fdac59106b254e8a022277bbf5c1213630bcfe [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/media/audio/audio_core/pipeline_config.h"
namespace media::audio {
Format PipelineConfig::OutputFormat(EffectsLoaderV2* effects_loader_v2) const {
auto channels = OutputChannels(effects_loader_v2);
auto result = Format::Create({
.sample_format = fuchsia::media::AudioSampleFormat::FLOAT,
.channels = channels,
.frames_per_second = static_cast<uint32_t>(root_.output_rate),
});
FX_CHECK(result.is_ok()) << "bad format: channels=" << channels << " fps=" << root_.output_rate;
return result.value();
}
uint32_t PipelineConfig::OutputChannels(EffectsLoaderV2* effects_loader_v2) const {
// If no effect performs rechannelization, then our channelization is determined
// by the mix stage itself.
const auto default_output_channels = root_.output_channels;
if (!root_.effects_v1.empty()) {
// The bottommost effect that defines output_channels will define our channelization.
for (auto it = root_.effects_v1.rbegin(); it != root_.effects_v1.rend(); ++it) {
if (it->output_channels) {
return *it->output_channels;
}
}
} else if (root_.effects_v2.has_value()) {
FX_CHECK(effects_loader_v2);
// Loading this effect will create a shared channel and VMOs to communicate with the
// FIDL server. We immediately drop those channels here. This is slightly wasteful,
// but simpler than trying to memoize this config so it can be loaded just once.
const std::string& name = root_.effects_v2->instance_name;
auto config_result = effects_loader_v2->GetProcessorConfiguration(name);
if (!config_result.ok() || config_result->is_error()) {
auto status = !config_result.ok() ? config_result.status() : config_result->error_value();
FX_PLOGS(ERROR, status) << "Cannot load V2 effect '" << name << "'";
return default_output_channels;
}
auto& config = config_result->value()->processor_configuration;
if (!config.has_outputs() || config.outputs().count() != 1 ||
!config.outputs()[0].has_format()) {
FX_LOGS(ERROR) << "V2 effect '" << name << "'"
<< "must have exactly one output with a defined format";
return default_output_channels;
}
return config.outputs()[0].format().channel_count;
}
return default_output_channels;
}
} // namespace media::audio