diff --git a/chromecast/browser/cast_browser_main_parts.cc b/chromecast/browser/cast_browser_main_parts.cc
index 14fac696276e2..027d6224c9c1d 100644
--- a/chromecast/browser/cast_browser_main_parts.cc
+++ b/chromecast/browser/cast_browser_main_parts.cc
@@ -213,13 +213,11 @@ void AddDefaultCommandLineSwitches(base::CommandLine* command_line) {
 
 CastBrowserMainParts::CastBrowserMainParts(
     const content::MainFunctionParams& parameters,
-    URLRequestContextFactory* url_request_context_factory,
-    scoped_ptr<::media::AudioManagerFactory> audio_manager_factory)
+    URLRequestContextFactory* url_request_context_factory)
     : BrowserMainParts(),
       cast_browser_process_(new CastBrowserProcess()),
       parameters_(parameters),
       url_request_context_factory_(url_request_context_factory),
-      audio_manager_factory_(audio_manager_factory.Pass()),
       net_log_(new CastNetLog()) {
   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
   AddDefaultCommandLineSwitches(command_line);
@@ -236,10 +234,6 @@ void CastBrowserMainParts::PreMainMessageLoopStart() {
   // Net/DNS metrics.
   metrics::PreregisterAllGroupedHistograms();
 
-  // Set the platform's implementation of AudioManagerFactory.
-  if (audio_manager_factory_)
-    ::media::AudioManager::SetFactory(audio_manager_factory_.release());
-
 #if defined(OS_ANDROID)
   net::NetworkChangeNotifier::SetFactory(
       new net::NetworkChangeNotifierFactoryAndroid());
@@ -273,6 +267,12 @@ int CastBrowserMainParts::PreCreateThreads() {
   CHECK(PathService::Get(DIR_CAST_HOME, &home_dir));
   if (!base::CreateDirectory(home_dir))
     return 1;
+
+  // AudioManager is created immediately after threads are created, requiring
+  // AudioManagerFactory to be set beforehand.
+  scoped_ptr< ::media::AudioManagerFactory> audio_manager_factory =
+      cast_browser_process_->browser_client()->CreateAudioManagerFactory();
+  ::media::AudioManager::SetFactory(audio_manager_factory.release());
 #endif
 
 #if defined(USE_AURA)
diff --git a/chromecast/browser/cast_browser_main_parts.h b/chromecast/browser/cast_browser_main_parts.h
index 4b5b5d8dfb9bd..6acd6d00f2609 100644
--- a/chromecast/browser/cast_browser_main_parts.h
+++ b/chromecast/browser/cast_browser_main_parts.h
@@ -6,15 +6,10 @@
 #define CHROMECAST_BROWSER_CAST_BROWSER_MAIN_PARTS_H_
 
 #include "base/macros.h"
-#include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "content/public/browser/browser_main_parts.h"
 #include "content/public/common/main_function_params.h"
 
-namespace media {
-class AudioManagerFactory;
-}
-
 namespace net {
 class NetLog;
 }
@@ -27,10 +22,8 @@ class URLRequestContextFactory;
 class CastBrowserMainParts : public content::BrowserMainParts {
  public:
   // This class does not take ownership of |url_request_content_factory|.
-  CastBrowserMainParts(
-      const content::MainFunctionParams& parameters,
-      URLRequestContextFactory* url_request_context_factory,
-      scoped_ptr<::media::AudioManagerFactory> audio_manager_factory);
+  CastBrowserMainParts(const content::MainFunctionParams& parameters,
+                       URLRequestContextFactory* url_request_context_factory);
   ~CastBrowserMainParts() override;
 
   // content::BrowserMainParts implementation:
@@ -45,7 +38,6 @@ class CastBrowserMainParts : public content::BrowserMainParts {
   scoped_ptr<CastBrowserProcess> cast_browser_process_;
   const content::MainFunctionParams parameters_;  // For running browser tests.
   URLRequestContextFactory* const url_request_context_factory_;
-  scoped_ptr<::media::AudioManagerFactory> audio_manager_factory_;
   scoped_ptr<net::NetLog> net_log_;
 
   DISALLOW_COPY_AND_ASSIGN(CastBrowserMainParts);
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc
index 744e66d70fdae..20c4361633dd5 100644
--- a/chromecast/browser/cast_content_browser_client.cc
+++ b/chromecast/browser/cast_content_browser_client.cc
@@ -80,18 +80,12 @@ scoped_ptr<CastService> CastContentBrowserClient::CreateCastService(
   return make_scoped_ptr(new CastServiceSimple(browser_context, pref_service));
 }
 
+#if !defined(OS_ANDROID)
 scoped_ptr<::media::AudioManagerFactory>
 CastContentBrowserClient::CreateAudioManagerFactory() {
-#if defined(OS_ANDROID)
-  // Return nullptr. The factory will not be set, and the default
-  // implementation of AudioManager will be used.
-  return scoped_ptr<::media::AudioManagerFactory>();
-#else
   return make_scoped_ptr(new media::CastAudioManagerFactory());
-#endif
 }
 
-#if !defined(OS_ANDROID)
 scoped_refptr<media::CmaMediaPipelineClient>
 CastContentBrowserClient::CreateCmaMediaPipelineClient() {
   return make_scoped_refptr(new media::CmaMediaPipelineClient());
@@ -101,7 +95,7 @@ scoped_ptr<::media::BrowserCdmFactory>
 CastContentBrowserClient::CreateBrowserCdmFactory() {
   return make_scoped_ptr(new media::CastBrowserCdmFactory());
 }
-#endif
+#endif  // OS_ANDROID
 
 void CastContentBrowserClient::ProcessExiting() {
   // Finalize CastMediaShlib on media thread to ensure it's not accessed
@@ -124,9 +118,8 @@ bool CastContentBrowserClient::EnableRemoteDebuggingImmediately() {
 
 content::BrowserMainParts* CastContentBrowserClient::CreateBrowserMainParts(
     const content::MainFunctionParams& parameters) {
-  content::BrowserMainParts* parts = new CastBrowserMainParts(
-      parameters, url_request_context_factory_.get(),
-      CreateAudioManagerFactory());
+  content::BrowserMainParts* parts =
+      new CastBrowserMainParts(parameters, url_request_context_factory_.get());
   CastBrowserProcess::GetInstance()->SetCastContentBrowserClient(this);
   return parts;
 }
diff --git a/chromecast/browser/cast_content_browser_client.h b/chromecast/browser/cast_content_browser_client.h
index 2e82fc848189b..11763b8b04165 100644
--- a/chromecast/browser/cast_content_browser_client.h
+++ b/chromecast/browser/cast_content_browser_client.h
@@ -61,10 +61,9 @@ class CastContentBrowserClient : public content::ContentBrowserClient {
       PrefService* pref_service,
       net::URLRequestContextGetter* request_context_getter);
 
-  // Provide an AudioManagerFactory instance for WebAudio playback.
+#if !defined(OS_ANDROID)
   virtual scoped_ptr<::media::AudioManagerFactory> CreateAudioManagerFactory();
 
-#if !defined(OS_ANDROID)
   // Creates a CmaMediaPipelineClient which is responsible to create (CMA
   // backend)
   // for media playback and watch media pipeline status, called once per media
diff --git a/chromecast/media/audio/cast_audio_manager.cc b/chromecast/media/audio/cast_audio_manager.cc
index 5aef07c8ef366..eaed75467affd 100644
--- a/chromecast/media/audio/cast_audio_manager.cc
+++ b/chromecast/media/audio/cast_audio_manager.cc
@@ -4,12 +4,10 @@
 
 #include "chromecast/media/audio/cast_audio_manager.h"
 
-#include "chromecast/base/task_runner_impl.h"
 #include "chromecast/media/audio/cast_audio_output_stream.h"
 #include "chromecast/media/base/media_message_loop.h"
 #include "chromecast/public/cast_media_shlib.h"
 #include "chromecast/public/media/media_pipeline_backend.h"
-#include "chromecast/public/media/media_pipeline_device_params.h"
 
 namespace {
 // TODO(alokp): Query the preferred value from media backend.
@@ -60,17 +58,12 @@ void CastAudioManager::GetAudioInputDeviceNames(
       ::media::CHANNEL_LAYOUT_STEREO, 48000, 16, 1024);
 }
 
-scoped_ptr<MediaPipelineBackend>
-CastAudioManager::CreateMediaPipelineBackend() {
+scoped_ptr<MediaPipelineBackend> CastAudioManager::CreateMediaPipelineBackend(
+    const MediaPipelineDeviceParams& params) {
   DCHECK(media::MediaMessageLoop::GetTaskRunner()->BelongsToCurrentThread());
 
-  if (!backend_task_runner_)
-    backend_task_runner_.reset(new TaskRunnerImpl());
-
-  MediaPipelineDeviceParams device_params(
-      MediaPipelineDeviceParams::kModeIgnorePts, backend_task_runner_.get());
   return scoped_ptr<MediaPipelineBackend>(
-      CastMediaShlib::CreateMediaPipelineBackend(device_params));
+      CastMediaShlib::CreateMediaPipelineBackend(params));
 }
 
 ::media::AudioOutputStream* CastAudioManager::MakeLinearOutputStream(
diff --git a/chromecast/media/audio/cast_audio_manager.h b/chromecast/media/audio/cast_audio_manager.h
index ff3bc43950763..f2cec7e1d556e 100644
--- a/chromecast/media/audio/cast_audio_manager.h
+++ b/chromecast/media/audio/cast_audio_manager.h
@@ -15,6 +15,7 @@ class TaskRunnerImpl;
 namespace media {
 
 class MediaPipelineBackend;
+struct MediaPipelineDeviceParams;
 
 class CastAudioManager : public ::media::AudioManagerBase {
  public:
@@ -32,7 +33,8 @@ class CastAudioManager : public ::media::AudioManagerBase {
 
   // This must be called on cast media thread.
   // See chromecast::media::MediaMessageLoop.
-  virtual scoped_ptr<MediaPipelineBackend> CreateMediaPipelineBackend();
+  virtual scoped_ptr<MediaPipelineBackend> CreateMediaPipelineBackend(
+      const MediaPipelineDeviceParams& params);
 
  private:
   // AudioManagerBase implementation.
@@ -51,8 +53,6 @@ class CastAudioManager : public ::media::AudioManagerBase {
       const std::string& output_device_id,
       const ::media::AudioParameters& input_params) override;
 
-  scoped_ptr<TaskRunnerImpl> backend_task_runner_;
-
   DISALLOW_COPY_AND_ASSIGN(CastAudioManager);
 };
 
diff --git a/chromecast/media/audio/cast_audio_output_stream.cc b/chromecast/media/audio/cast_audio_output_stream.cc
index bb7a54efce7dc..a6cba305a91df 100644
--- a/chromecast/media/audio/cast_audio_output_stream.cc
+++ b/chromecast/media/audio/cast_audio_output_stream.cc
@@ -8,6 +8,7 @@
 #include "base/synchronization/waitable_event.h"
 #include "base/threading/thread_checker.h"
 #include "chromecast/base/metrics/cast_metrics_helper.h"
+#include "chromecast/base/task_runner_impl.h"
 #include "chromecast/media/audio/cast_audio_manager.h"
 #include "chromecast/media/base/media_message_loop.h"
 #include "chromecast/media/cma/base/cast_decoder_buffer_impl.h"
@@ -18,6 +19,7 @@
 #include "chromecast/public/media/decrypt_context.h"
 #include "chromecast/public/media/media_clock_device.h"
 #include "chromecast/public/media/media_pipeline_backend.h"
+#include "chromecast/public/media/media_pipeline_device_params.h"
 #include "media/base/bind_to_current_loop.h"
 #include "media/base/decoder_buffer.h"
 
@@ -85,8 +87,12 @@ class CastAudioOutputStream::Backend {
     DCHECK(thread_checker_.CalledOnValidThread());
     DCHECK(backend_ == nullptr);
 
+    backend_task_runner_.reset(new TaskRunnerImpl());
+    MediaPipelineDeviceParams device_params(
+        MediaPipelineDeviceParams::kModeIgnorePts, backend_task_runner_.get());
+
     scoped_ptr<MediaPipelineBackend> pipeline_backend =
-        audio_manager->CreateMediaPipelineBackend();
+        audio_manager->CreateMediaPipelineBackend(device_params);
     if (pipeline_backend && InitClockDevice(pipeline_backend->GetClock()) &&
         InitAudioDevice(audio_params_, pipeline_backend->GetAudio())) {
       backend_ = pipeline_backend.Pass();
@@ -103,6 +109,7 @@ class CastAudioOutputStream::Backend {
       backend_->GetAudio()->SetState(AudioPipelineDevice::kStateIdle);
     }
     backend_.reset();
+    backend_task_runner_.reset();
   }
 
   void Start() {
@@ -157,6 +164,7 @@ class CastAudioOutputStream::Backend {
 
   const ::media::AudioParameters audio_params_;
   scoped_ptr<MediaPipelineBackend> backend_;
+  scoped_ptr<TaskRunnerImpl> backend_task_runner_;
   base::ThreadChecker thread_checker_;
   DISALLOW_COPY_AND_ASSIGN(Backend);
 };
diff --git a/chromecast/media/audio/cast_audio_output_stream_unittest.cc b/chromecast/media/audio/cast_audio_output_stream_unittest.cc
index a6679d8588afa..f96ebc3510a27 100644
--- a/chromecast/media/audio/cast_audio_output_stream_unittest.cc
+++ b/chromecast/media/audio/cast_audio_output_stream_unittest.cc
@@ -182,7 +182,8 @@ class FakeAudioManager : public CastAudioManager {
   ~FakeAudioManager() override {}
 
   // CastAudioManager overrides.
-  scoped_ptr<MediaPipelineBackend> CreateMediaPipelineBackend() override {
+  scoped_ptr<MediaPipelineBackend> CreateMediaPipelineBackend(
+      const MediaPipelineDeviceParams& params) override {
     DCHECK(media::MediaMessageLoop::GetTaskRunner()->BelongsToCurrentThread());
     DCHECK(!media_pipeline_backend_);