blob: d716cff71ddb061fa3c202de6fa7ff48f444c032 [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_MIX_STAGE_H_
#define SRC_MEDIA_AUDIO_AUDIO_CORE_MIX_STAGE_H_
#include <lib/async/cpp/task.h>
#include <lib/async/cpp/time.h>
#include <lib/media/cpp/timeline_function.h>
#include <lib/zx/time.h>
#include "src/lib/fxl/synchronization/thread_annotations.h"
#include "src/media/audio/audio_core/format.h"
#include "src/media/audio/audio_core/mixer/mixer.h"
#include "src/media/audio/audio_core/stream.h"
#include "src/media/audio/audio_core/versioned_timeline_function.h"
namespace media::audio {
class MixStage : public ReadableStream {
public:
MixStage(const Format& output_format, uint32_t block_size,
TimelineFunction reference_clock_to_fractional_frame);
MixStage(const Format& output_format, uint32_t block_size,
fbl::RefPtr<VersionedTimelineFunction> reference_clock_to_fractional_frame);
struct FrameSpan {
int64_t start;
uint32_t length;
};
// |media::audio::ReadableStream|
std::optional<ReadableStream::Buffer> ReadLock(zx::time ref_time, int64_t frame,
uint32_t frame_count) override;
void Trim(zx::time ref_time) override;
TimelineFunctionSnapshot ReferenceClockToFractionalFrames() const override;
void SetMinLeadTime(zx::duration min_lead_time) override;
std::shared_ptr<Mixer> AddInput(std::shared_ptr<ReadableStream> stream,
Mixer::Resampler sampler_hint = Mixer::Resampler::Default);
void RemoveInput(const ReadableStream& stream);
private:
MixStage(std::shared_ptr<WritableStream> output_stream);
void SetupMixBuffer(uint32_t max_mix_frames);
struct MixJob {
// Job state set up once by an output implementation, used by all renderers.
float* buf;
uint32_t buf_frames;
int64_t start_pts_of; // start PTS, expressed in output frames.
uint32_t reference_clock_to_fractional_destination_frame_gen;
bool accumulate;
TimelineFunction reference_clock_to_fractional_destination_frame;
// Per-stream job state, set up for each renderer during SetupMix.
uint32_t frames_produced;
};
// TODO(13415): Integrate it into the Mixer class itself.
void UpdateSourceTrans(const ReadableStream& stream, Mixer::Bookkeeping* bk);
void UpdateDestTrans(const MixJob& job, Mixer::Bookkeeping* bk);
enum class TaskType { Mix, Trim };
void ForEachSource(TaskType task_type, zx::time ref_time);
void SetupMix(Mixer* mixer);
bool ProcessMix(ReadableStream* stream, Mixer* mixer, const ReadableStream::Buffer& buffer);
void MixStream(ReadableStream* stream, Mixer* mixer, zx::time ref_time);
struct StreamHolder {
std::shared_ptr<ReadableStream> stream;
std::shared_ptr<Mixer> mixer;
};
std::mutex stream_lock_;
std::vector<StreamHolder> streams_ FXL_GUARDED_BY(stream_lock_);
std::shared_ptr<WritableStream> output_stream_;
// State used by the mix task.
MixJob cur_mix_job_;
};
} // namespace media::audio
#endif // SRC_MEDIA_AUDIO_AUDIO_CORE_MIX_STAGE_H_