Commit dfd7dfd5 authored by Guohui Deng's avatar Guohui Deng Committed by Commit Bot

AudioOutputStream Uses MixerService

When appropriate, AudioOutputStream uses MixerService for
lower latency audio playback.

Bug: internal b/29571387
Test: Play a lasting sin wave audio on two devices, to make
sure the AudioOutputStream plays fine whether or not
MixerService is used.

Change-Id: Ieebd53ee5ecdc1c6e249601366d82de30c5d9119
Reviewed-on: https://chromium-review.googlesource.com/c/1271007Reviewed-by: default avatarKenneth MacKay <kmackay@chromium.org>
Commit-Queue: Guohui Deng <guohuideng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#599763}
parent c6bc8193
...@@ -19,6 +19,8 @@ cast_source_set("audio") { ...@@ -19,6 +19,8 @@ cast_source_set("audio") {
"//base", "//base",
"//chromecast/base", "//chromecast/base",
"//chromecast/common/mojom", "//chromecast/common/mojom",
"//chromecast/media/audio/mixer_service:connection",
"//chromecast/media/audio/mixer_service:proto",
"//chromecast/media/base", "//chromecast/media/base",
"//chromecast/media/cma/backend", "//chromecast/media/cma/backend",
"//chromecast/media/cma/base", "//chromecast/media/cma/base",
......
...@@ -33,16 +33,19 @@ enum AudioOutputState { ...@@ -33,16 +33,19 @@ enum AudioOutputState {
class CastAudioManager; class CastAudioManager;
// Chromecast implementation of AudioOutputStream that forwards to CMA backend. // Chromecast implementation of AudioOutputStream.
// This class forwards to MixerService if Direct Audio is available for
// a lower latency audio playback (using MixerServiceWrapper), otherwise
// it forwards to CMA backend (using CmaWrapper).
// //
// This class lives inside two threads: // In either case, involved components live on two threads:
// 1. Audio thread // 1. Audio thread
// |CastAudioOutputStream| // |CastAudioOutputStream|
// Where the object gets construction from AudioManager. // Where the object gets construction from AudioManager.
// How the object gets controlled from AudioManager. // How the object gets controlled from AudioManager.
// 2. Media thread // 2. Media thread or an IO thread opened within |AudioOutputStream|.
// |CastAudioOutputStream::CmaWrapper| // |CastAudioOutputStream::CmaWrapper| or |MixerServiceWrapper| lives on
// All CMA logic lives in this thread. // this thread.
// //
// The interface between AudioManager and AudioOutputStream is synchronous, so // The interface between AudioManager and AudioOutputStream is synchronous, so
// in order to allow asynchronous thread hops, we: // in order to allow asynchronous thread hops, we:
...@@ -51,8 +54,10 @@ class CastAudioManager; ...@@ -51,8 +54,10 @@ class CastAudioManager;
// //
// The individual thread states should nearly always be the same. The only time // The individual thread states should nearly always be the same. The only time
// they are expected to be different is when the audio thread has executed a // they are expected to be different is when the audio thread has executed a
// task and posted to the media thread, but the media thread has not executed // task and posted to the media thread/IO thread, but the media thread has not
// yet. // executed yet.
//
// The below illustrates the case when CMA backend is used for playback.
// //
// Audio Thread |CAOS| Media Thread |CmaWrapper| // Audio Thread |CAOS| Media Thread |CmaWrapper|
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ // ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
...@@ -76,9 +81,17 @@ class CastAudioManager; ...@@ -76,9 +81,17 @@ class CastAudioManager;
// | // |
// v // v
// ( released) // ( released)
//
// * Initial states. // * Initial states.
// ** Final states. // ** Final states.
//
// When MixerService is used in place of CMA backend, the state transition is
// similar but a little simpler.
// MixerServiceWrapper creates a new MixerServiceConnection at Start() and
// destroys the MixerServiceConnection at Stop(). When the volume is adjusted
// between a Stop() and the next Start(), the volume is recorded and then
// applied to MixerServiceConnection after the MixerServiceConnection is
// established on the Start() call.
class CastAudioOutputStream : public ::media::AudioOutputStream { class CastAudioOutputStream : public ::media::AudioOutputStream {
public: public:
CastAudioOutputStream(CastAudioManager* audio_manager, CastAudioOutputStream(CastAudioManager* audio_manager,
...@@ -96,6 +109,7 @@ class CastAudioOutputStream : public ::media::AudioOutputStream { ...@@ -96,6 +109,7 @@ class CastAudioOutputStream : public ::media::AudioOutputStream {
private: private:
class CmaWrapper; class CmaWrapper;
class MixerServiceWrapper;
void FinishClose(); void FinishClose();
void OnGetMultiroomInfo(const std::string& application_session_id, void OnGetMultiroomInfo(const std::string& application_session_id,
...@@ -110,6 +124,7 @@ class CastAudioOutputStream : public ::media::AudioOutputStream { ...@@ -110,6 +124,7 @@ class CastAudioOutputStream : public ::media::AudioOutputStream {
const ::media::AudioParameters audio_params_; const ::media::AudioParameters audio_params_;
chromecast::mojom::MultiroomManagerPtr multiroom_manager_; chromecast::mojom::MultiroomManagerPtr multiroom_manager_;
std::unique_ptr<CmaWrapper> cma_wrapper_; std::unique_ptr<CmaWrapper> cma_wrapper_;
std::unique_ptr<MixerServiceWrapper> mixer_service_wrapper_;
// Hold bindings to Start and SetVolume if they were called before Open // Hold bindings to Start and SetVolume if they were called before Open
// completed. After initialization has finished, these bindings will be // completed. After initialization has finished, these bindings will be
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment