blob: 1135acfd97d624731936ad50eb19722f44b978be [file] [log] [blame]
// Copyright 2019 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.
#ifndef SRC_MEDIA_AUDIO_AUDIO_CORE_OUTPUT_PIPELINE_H_
#define SRC_MEDIA_AUDIO_AUDIO_CORE_OUTPUT_PIPELINE_H_
#include <lib/media/cpp/timeline_function.h>
#include <vector>
#include <fbl/ref_ptr.h>
#include <trace/event.h>
#include "src/lib/syslog/cpp/logger.h"
#include "src/media/audio/audio_core/effects_stage.h"
#include "src/media/audio/audio_core/mix_stage.h"
#include "src/media/audio/audio_core/pipeline_config.h"
#include "src/media/audio/audio_core/stream.h"
#include "src/media/audio/audio_core/stream_usage.h"
namespace media::audio {
class OutputPipeline : public Stream {
public:
// Creates an |OutputPipeline| based on the specification in |config|. The pipeline will
// ultimately produce output frames via |LockBuffer| in the |output_format| requested.
//
// |max_block_size_frames| is the largest contiguous region that may be returned from
// |LockBuffer|. If a caller requests a frame region of more that |max_block_size_frames|, then
// the pipeline will truncate this to only |max_block_size_frames| and the caller will have to
// call |LockBuffer| again to mix the subsequent frames.
//
// |ref_clock_to_fractional_frame| is a timeline function that will compute the output frame
// number (in fixed point format with 13 bits of fractional precision) based on a reference
// timestamp.
//
// The |sampler| is optionally used to select the type of sampler to be used when joining
// mix stages together.
OutputPipeline(const PipelineConfig& config, uint32_t channels, uint32_t max_block_size_frames,
TimelineFunction reference_clock_to_fractional_frame,
Mixer::Resampler sampler = Mixer::Resampler::Default);
// Returns the loopback |Stream| for this pipeline.
std::shared_ptr<Stream> loopback() const { return loopback_; }
// Adds |stream| as an input to be mixed. The given |usage| will indicate where in the pipeline
// this stream will be routed (based on the |PipelineConfig| this pipeline was created with).
std::shared_ptr<Mixer> AddInput(std::shared_ptr<Stream> stream, const StreamUsage& usage,
Mixer::Resampler sampler_hint = Mixer::Resampler::Default);
// Removes |stream| from the pipeline.
//
// It is an error to call |RemoveInput| without exactly one preceeding call to |AddInput| with the
// same |stream|.
void RemoveInput(const Stream& stream);
// Sets the configuration of all effects with the given instance name.
void SetEffectConfig(const std::string& instance_name, const std::string& config);
// |media::audio::Stream|
std::optional<Stream::Buffer> LockBuffer(zx::time ref_time, int64_t frame,
uint32_t frame_count) override {
TRACE_DURATION("audio", "OutputPipeline::LockBuffer");
FX_DCHECK(stream_);
return stream_->LockBuffer(ref_time, frame, frame_count);
}
void UnlockBuffer(bool release_buffer) override {
TRACE_DURATION("audio", "OutputPipeline::UnlockBuffer");
FX_DCHECK(stream_);
stream_->UnlockBuffer(release_buffer);
}
void Trim(zx::time trim) override {
TRACE_DURATION("audio", "OutputPipeline::Trim");
FX_CHECK(stream_);
stream_->Trim(trim);
}
TimelineFunctionSnapshot ReferenceClockToFractionalFrames() const override {
TRACE_DURATION("audio", "OutputPipeline::ReferenceClockToFractionalFrames");
FX_DCHECK(stream_);
return stream_->ReferenceClockToFractionalFrames();
}
private:
std::shared_ptr<Stream> CreateMixStage(
const PipelineConfig::MixGroup& spec, uint32_t channels, uint32_t block_size,
fbl::RefPtr<VersionedTimelineFunction> ref_clock_to_output_frame, uint32_t* usage_mask,
Mixer::Resampler sampler);
MixStage& LookupStageForUsage(const StreamUsage& usage);
std::vector<std::pair<std::shared_ptr<MixStage>, std::vector<StreamUsage>>> mix_stages_;
std::vector<std::shared_ptr<EffectsStage>> effects_stages_;
std::vector<std::pair<std::shared_ptr<Stream>, StreamUsage>> streams_;
// This is the root of the mix graph. The other mix stages must be reachable from this node
// to actually get mixed.
std::shared_ptr<Stream> stream_;
std::shared_ptr<Stream> loopback_;
};
} // namespace media::audio
#endif // SRC_MEDIA_AUDIO_AUDIO_CORE_OUTPUT_PIPELINE_H_