| // 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/context.h" |
| |
| #include "src/media/audio/audio_core/activity_dispatcher.h" |
| #include "src/media/audio/audio_core/audio_admin.h" |
| #include "src/media/audio/audio_core/audio_device_manager.h" |
| #include "src/media/audio/audio_core/audio_impl.h" |
| #include "src/media/audio/audio_core/audio_tuner_impl.h" |
| #include "src/media/audio/audio_core/effects_controller_impl.h" |
| #include "src/media/audio/audio_core/link_matrix.h" |
| #include "src/media/audio/audio_core/plug_detector.h" |
| #include "src/media/audio/audio_core/route_graph.h" |
| #include "src/media/audio/audio_core/stream_volume_manager.h" |
| #include "src/media/audio/audio_core/threading_model.h" |
| #include "src/media/audio/audio_core/throttle_output.h" |
| #include "src/media/audio/audio_core/usage_gain_reporter_impl.h" |
| #include "src/media/audio/audio_core/usage_reporter_impl.h" |
| |
| namespace media::audio { |
| namespace { |
| |
| // All audio renderer buffers will need to fit within this VMAR. We want to choose a size here large |
| // enough that will accomodate all the mappings required by all clients while also being small |
| // enough to avoid unnecessary page table fragmentation. |
| constexpr size_t kAudioRendererVmarSize = 16ull * 1024 * 1024 * 1024; |
| constexpr zx_vm_option_t kAudioRendererVmarFlags = |
| ZX_VM_COMPACT | ZX_VM_CAN_MAP_READ | ZX_VM_CAN_MAP_WRITE | ZX_VM_ALIGN_1GB; |
| |
| class ContextImpl : public Context { |
| public: |
| ContextImpl(std::unique_ptr<ThreadingModel> threading_model, |
| std::unique_ptr<sys::ComponentContext> component_context, |
| std::unique_ptr<PlugDetector> plug_detector, ProcessConfig process_config) |
| : threading_model_(std::move(threading_model)), |
| component_context_(std::move(component_context)), |
| process_config_(std::move(process_config)), |
| route_graph_(&link_matrix_), |
| device_manager_(*threading_model_, std::move(plug_detector), route_graph_, link_matrix_, |
| process_config_), |
| stream_volume_manager_(threading_model_->FidlDomain().dispatcher(), |
| process_config_.default_render_usage_volumes()), |
| audio_admin_(&stream_volume_manager_, threading_model_->FidlDomain().dispatcher(), |
| &usage_reporter_, &activity_dispatcher_), |
| vmar_manager_( |
| fzl::VmarManager::Create(kAudioRendererVmarSize, nullptr, kAudioRendererVmarFlags)), |
| usage_gain_reporter_(this), |
| effects_controller_(*this), |
| audio_tuner_(*this), |
| audio_(this) { |
| FX_DCHECK(vmar_manager_ != nullptr) << "Failed to allocate VMAR"; |
| |
| zx_status_t res = device_manager_.Init(); |
| FX_DCHECK(res == ZX_OK); |
| |
| auto throttle = ThrottleOutput::Create(threading_model_.get(), &device_manager_, &link_matrix_); |
| throttle_output_ = throttle.get(); |
| route_graph_.SetThrottleOutput(threading_model_.get(), std::move(throttle)); |
| } |
| |
| // Disallow copy & move. |
| ContextImpl(ContextImpl&& o) = delete; |
| ContextImpl& operator=(ContextImpl&& o) = delete; |
| ContextImpl(const ContextImpl&) = delete; |
| ContextImpl& operator=(const ContextImpl&) = delete; |
| |
| ~ContextImpl() override = default; |
| |
| // |fuchsia::audio::Context| |
| void PublishOutgoingServices() override { |
| component_context_->outgoing()->AddPublicService(audio_.GetFidlRequestHandler()); |
| component_context_->outgoing()->AddPublicService(device_manager_.GetFidlRequestHandler()); |
| component_context_->outgoing()->AddPublicService(usage_reporter_.GetFidlRequestHandler()); |
| component_context_->outgoing()->AddPublicService(activity_dispatcher_.GetFidlRequestHandler()); |
| component_context_->outgoing()->AddPublicService(usage_gain_reporter_.GetFidlRequestHandler()); |
| component_context_->outgoing()->AddPublicService(audio_tuner_.GetFidlRequestHandler()); |
| component_context_->outgoing()->AddPublicService(effects_controller_.GetFidlRequestHandler()); |
| } |
| ThreadingModel& threading_model() override { return *threading_model_; } |
| AudioDeviceManager& device_manager() override { return device_manager_; } |
| AudioAdmin& audio_admin() override { return audio_admin_; } |
| fbl::RefPtr<fzl::VmarManager> vmar() const override { return vmar_manager_; } |
| StreamVolumeManager& volume_manager() override { return stream_volume_manager_; } |
| RouteGraph& route_graph() override { return route_graph_; } |
| LinkMatrix& link_matrix() override { return link_matrix_; } |
| const ProcessConfig& process_config() const override { return process_config_; } |
| sys::ComponentContext& component_context() override { return *component_context_; } |
| AudioOutput* throttle_output() const override { return throttle_output_; } |
| |
| private: |
| std::unique_ptr<ThreadingModel> threading_model_; |
| std::unique_ptr<sys::ComponentContext> component_context_; |
| ProcessConfig process_config_; |
| |
| AudioOutput* throttle_output_; |
| |
| LinkMatrix link_matrix_; |
| RouteGraph route_graph_; |
| |
| // State for dealing with devices. |
| AudioDeviceManager device_manager_; |
| |
| // Router for volume changes. |
| StreamVolumeManager stream_volume_manager_; |
| |
| UsageReporterImpl usage_reporter_; |
| |
| // Dispatcher for audio activity. |
| ActivityDispatcherImpl activity_dispatcher_; |
| |
| // Audio usage manager |
| AudioAdmin audio_admin_; |
| |
| // We allocate a sub-vmar to hold the audio renderer buffers. Keeping these in a sub-vmar allows |
| // us to take advantage of ASLR while minimizing page table fragmentation. |
| fbl::RefPtr<fzl::VmarManager> vmar_manager_; |
| |
| UsageGainReporterImpl usage_gain_reporter_; |
| |
| EffectsControllerImpl effects_controller_; |
| AudioTunerImpl audio_tuner_; |
| |
| // FIDL service that forwards requests to AudioCore. |
| AudioImpl audio_; |
| }; |
| |
| } // namespace |
| |
| std::unique_ptr<Context> Context::Create(std::unique_ptr<ThreadingModel> threading_model, |
| std::unique_ptr<sys::ComponentContext> component_context, |
| std::unique_ptr<PlugDetector> plug_detector, |
| ProcessConfig process_config) { |
| return std::make_unique<ContextImpl>(std::move(threading_model), std::move(component_context), |
| std::move(plug_detector), std::move(process_config)); |
| } |
| |
| } // namespace media::audio |