#ifndef FUCHSIA_WEB_WEBENGINE_RENDERER_WEB_ENGINE_AUDIO_OUTPUT_DEVICE_H_
#define FUCHSIA_WEB_WEBENGINE_RENDERER_WEB_ENGINE_AUDIO_OUTPUT_DEVICE_H_
#include <fuchsia/media/cpp/fidl.h>
#include <memory>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/shared_memory_mapping.h"
#include "base/synchronization/lock.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "base/types/pass_key.h"
#include "fuchsia_web/webengine/web_engine_export.h"
#include "media/base/audio_renderer_sink.h"
namespace base {
class SingleThreadTaskRunner;
class WritableSharedMemoryMapping;
}
class WEB_ENGINE_EXPORT WebEngineAudioOutputDevice
: public media::AudioRendererSink {
public:
static scoped_refptr<WebEngineAudioOutputDevice> Create(
fidl::InterfaceHandle<fuchsia::media::AudioConsumer>
audio_consumer_handle,
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
static scoped_refptr<WebEngineAudioOutputDevice> CreateOnDefaultThread(
fidl::InterfaceHandle<fuchsia::media::AudioConsumer>
audio_consumer_handle);
WebEngineAudioOutputDevice(
base::PassKey<WebEngineAudioOutputDevice>,
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
void Initialize(const media::AudioParameters& params,
RenderCallback* callback) override;
void Start() override;
void Stop() override;
void Pause() override;
void Play() override;
void Flush() override;
bool SetVolume(double volume) override;
media::OutputDeviceInfo GetOutputDeviceInfo() override;
void GetOutputDeviceInfoAsync(OutputDeviceInfoCB info_cb) override;
bool IsOptimizedForHardwareParameters() override;
bool CurrentThreadIsRenderingThread() override;
private:
friend class WebEngineAudioOutputDeviceTest;
~WebEngineAudioOutputDevice() override;
void BindAudioConsumerOnAudioThread(
fidl::InterfaceHandle<fuchsia::media::AudioConsumer>
audio_consumer_handle);
void InitializeOnAudioThread(const media::AudioParameters& params);
void StartOnAudioThread();
void StopOnAudioThread();
void PauseOnAudioThread();
void PlayOnAudioThread();
void FlushOnAudioThread();
void SetVolumeOnAudioThread(double volume);
void CreateStreamSink();
void UpdateVolume();
void WatchAudioConsumerStatus();
void OnAudioConsumerStatusChanged(fuchsia::media::AudioConsumerStatus status);
void SchedulePumpSamples();
void PumpSamples(base::TimeTicks playback_time);
void OnStreamSendDone(size_t buffer_index);
void ReportError();
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
fuchsia::media::AudioConsumerPtr audio_consumer_;
fuchsia::media::StreamSinkPtr stream_sink_;
fuchsia::media::audio::VolumeControlPtr volume_control_;
media::AudioParameters params_;
base::Lock callback_lock_;
raw_ptr<RenderCallback> callback_ GUARDED_BY(callback_lock_) = nullptr;
std::vector<base::WritableSharedMemoryMapping> stream_sink_buffers_;
std::vector<size_t> available_buffers_indices_;
float volume_ = 1.0;
size_t media_pos_frames_ = 0;
base::TimeDelta min_lead_time_;
base::TimeTicks timeline_reference_time_;
base::TimeDelta timeline_subject_time_;
uint32_t timeline_reference_delta_;
uint32_t timeline_subject_delta_;
bool paused_ = false;
base::OneShotTimer pump_samples_timer_;
std::unique_ptr<media::AudioBus> audio_bus_;
};
#endif