blob: fd692fb521546bba1b399e607aaf6bd3871da8ac [file] [log] [blame]
// Copyright 2015 The Chromium 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 SERVICES_MEDIA_AUDIO_PLATFORM_GENERIC_STANDARD_OUTPUT_BASE_H_
#define SERVICES_MEDIA_AUDIO_PLATFORM_GENERIC_STANDARD_OUTPUT_BASE_H_
#include "base/callback.h"
#include "mojo/services/media/common/cpp/linear_transform.h"
#include "mojo/services/media/common/cpp/local_time.h"
#include "mojo/services/media/common/interfaces/media_common.mojom.h"
#include "mojo/services/media/common/interfaces/media_types.mojom.h"
#include "services/media/audio/audio_output.h"
#include "services/media/audio/audio_track_to_output_link.h"
#include "services/media/audio/gain.h"
#include "services/media/audio/platform/generic/mixer.h"
#include "services/media/audio/platform/generic/output_formatter.h"
namespace mojo {
namespace media {
namespace audio {
class StandardOutputBase : public AudioOutput {
public:
~StandardOutputBase() override;
protected:
struct MixJob {
static constexpr uint32_t INVALID_GENERATION = 0;
// State for the job set up once by the output implementation and then used
// by all tracks.
void* buf;
uint32_t buf_frames;
int64_t start_pts_of; // start PTS, expressed in output frames.
uint32_t local_to_output_gen;
bool accumulate;
const LinearTransform* local_to_output;
// State for the job which is set up for each track during SetupMix
uint32_t frames_produced;
};
struct TrackBookkeeping : public AudioTrackToOutputLink::Bookkeeping {
TrackBookkeeping();
~TrackBookkeeping() override;
LinearTransform lt_to_track_frames;
LinearTransform out_frames_to_track_frames;
uint32_t lt_to_track_frames_gen = 0;
uint32_t out_frames_to_track_frames_gen = MixJob::INVALID_GENERATION;
uint32_t step_size;
Gain::AScale amplitude_scale;
MixerPtr mixer;
void UpdateTrackTrans(const AudioTrackImplPtr& track);
void UpdateOutputTrans(const MixJob& job);
};
explicit StandardOutputBase(AudioOutputManager* manager);
void Process() final;
MediaResult InitializeLink(const AudioTrackToOutputLinkPtr& link) final;
void SetNextSchedTime(const LocalTime& next_sched_time) {
next_sched_time_ = next_sched_time;
next_sched_time_known_ = true;
}
void SetNextSchedDelay(const LocalDuration& next_sched_delay) {
SetNextSchedTime(LocalClock::now() + next_sched_delay);
}
virtual bool StartMixJob(MixJob* job, const LocalTime& process_start) = 0;
virtual bool FinishMixJob(const MixJob& job) = 0;
virtual TrackBookkeeping* AllocBookkeeping();
void SetupMixBuffer(uint32_t max_mix_frames);
// Details about the final output format
OutputFormatterPtr output_formatter_;
private:
using TrackSetupTask = std::function<bool(const AudioTrackImplPtr& track,
TrackBookkeeping* info)>;
using TrackProcessTask =
std::function<bool(const AudioTrackImplPtr& track,
TrackBookkeeping* info,
const AudioPipe::AudioPacketRefPtr& pkt_ref)>;
void ForeachTrack(const TrackSetupTask& setup,
const TrackProcessTask& process);
bool SetupMix(const AudioTrackImplPtr& track, TrackBookkeeping* info);
bool ProcessMix(const AudioTrackImplPtr& track,
TrackBookkeeping* info,
const AudioPipe::AudioPacketRefPtr& pkt_ref);
bool SetupTrim(const AudioTrackImplPtr& track, TrackBookkeeping* info);
bool ProcessTrim(const AudioTrackImplPtr& track,
TrackBookkeeping* info,
const AudioPipe::AudioPacketRefPtr& pkt_ref);
LocalTime next_sched_time_;
bool next_sched_time_known_;
// State for the internal buffer which holds intermediate mix results.
//
// TODO(johngro): Right now, the cannonical intermediate format is signed 32
// bit ints. As time goes on, we may need to reconsider this. This will
// become more important when...
//
// 1) We support 24 bit audio. Right now, with a 16 bit max, we can
// accumulate for up to a maximum of 2^16-1 tracks without needing to do
// anything special about about clipping. With 24 bit audio, this number
// will drop to only 255 simultanious tracks. It is unclear if this is a
// reasonable system-wide limitation or not.
// 2) We support floating point audio.
std::unique_ptr<int32_t> mix_buf_;
uint32_t mix_buf_frames_ = 0;
// State used by the mix task.
TrackSetupTask setup_mix_;
TrackProcessTask process_mix_;
MixJob cur_mix_job_;
// State used by the trim task.
TrackSetupTask setup_trim_;
TrackProcessTask process_trim_;
int64_t trim_threshold_;
};
} // namespace audio
} // namespace media
} // namespace mojo
#endif // SERVICES_MEDIA_AUDIO_PLATFORM_GENERIC_STANDARD_OUTPUT_BASE_H_