1 // Copyright 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROMECAST_MEDIA_AUDIO_CMA_AUDIO_OUTPUT_STREAM_H_ 6 #define CHROMECAST_MEDIA_AUDIO_CMA_AUDIO_OUTPUT_STREAM_H_ 7 8 #include <memory> 9 #include <string> 10 11 #include "base/callback.h" 12 #include "base/macros.h" 13 #include "base/memory/ref_counted.h" 14 #include "base/memory/weak_ptr.h" 15 #include "base/synchronization/lock.h" 16 #include "base/threading/thread_checker.h" 17 #include "base/time/time.h" 18 #include "base/timer/timer.h" 19 #include "chromecast/common/mojom/multiroom.mojom.h" 20 #include "chromecast/media/api/cma_backend.h" 21 #include "media/audio/audio_io.h" 22 #include "media/base/audio_parameters.h" 23 24 namespace base { 25 class WaitableEvent; 26 } // namespace base 27 28 namespace media { 29 class AudioBus; 30 } // namespace media 31 32 namespace chromecast { 33 34 class TaskRunnerImpl; 35 36 namespace media { 37 38 class CmaAudioOutput; 39 class CmaBackendFactory; 40 41 class CmaAudioOutputStream : public CmaBackend::Decoder::Delegate { 42 public: 43 CmaAudioOutputStream(const ::media::AudioParameters& audio_params, 44 base::TimeDelta buffer_duration, 45 const std::string& device_id, 46 CmaBackendFactory* cma_backend_factory); 47 ~CmaAudioOutputStream() override; 48 49 void SetRunning(bool running); 50 void Initialize(const std::string& application_session_id, 51 chromecast::mojom::MultiroomInfoPtr multiroom_info); 52 void Start(::media::AudioOutputStream::AudioSourceCallback* source_callback); 53 void Stop(base::WaitableEvent* finished); 54 void Flush(base::WaitableEvent* finished); 55 void Close(base::OnceClosure closure); 56 void SetVolume(double volume); 57 58 private: 59 enum class CmaBackendState { 60 kUninitialized, 61 kStopped, 62 kPaused, 63 kStarted, 64 kPendingClose, 65 }; 66 67 void PushBuffer(); 68 69 // CmaBackend::Decoder::Delegate implementation: OnEndOfStream()70 void OnEndOfStream() override {} 71 void OnDecoderError() override; OnKeyStatusChanged(const std::string & key_id,CastKeyStatus key_status,uint32_t system_code)72 void OnKeyStatusChanged(const std::string& key_id, 73 CastKeyStatus key_status, 74 uint32_t system_code) override {} OnVideoResolutionChanged(const Size & size)75 void OnVideoResolutionChanged(const Size& size) override {} 76 void OnPushBufferComplete(BufferStatus status) override; 77 78 const bool is_audio_prefetch_; 79 80 const ::media::AudioParameters audio_params_; 81 const std::string device_id_; 82 CmaBackendFactory* const cma_backend_factory_; 83 std::unique_ptr<CmaAudioOutput> output_; 84 85 base::Lock running_lock_; 86 bool running_ = true; 87 CmaBackendState cma_backend_state_ = CmaBackendState::kUninitialized; 88 const base::TimeDelta buffer_duration_; 89 std::unique_ptr<::media::AudioBus> audio_bus_; 90 base::OneShotTimer push_timer_; 91 bool push_in_progress_ = false; 92 bool encountered_error_ = false; 93 base::TimeTicks next_push_time_; 94 base::TimeTicks last_push_complete_time_; 95 base::TimeDelta last_rendering_delay_; 96 base::TimeDelta render_buffer_size_estimate_; 97 ::media::AudioOutputStream::AudioSourceCallback* source_callback_ = nullptr; 98 99 THREAD_CHECKER(media_thread_checker_); 100 101 DISALLOW_COPY_AND_ASSIGN(CmaAudioOutputStream); 102 }; 103 104 } // namespace media 105 } // namespace chromecast 106 107 #endif // CHROMECAST_MEDIA_AUDIO_CMA_AUDIO_OUTPUT_STREAM_H_ 108