--- a/src/webkit/glue/media/buffered_data_source.cc
+++ b/src/webkit/glue/media/buffered_data_source.cc
@@ -15,6 +15,7 @@
 #include "net/http/http_response_headers.h"
 #include "webkit/glue/media/buffered_data_source.h"
 #include "webkit/glue/webkit_glue.h"
+#include "webkit/glue/webmediaplayer_impl.h"
 
 namespace {
 
@@ -540,10 +541,12 @@ bool BufferedDataSource::IsMediaFormatSu
 // BufferedDataSource, protected
 BufferedDataSource::BufferedDataSource(
     MessageLoop* render_loop,
-    webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory)
+    webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory,
+    webkit_glue::WebMediaPlayerImpl::Proxy* proxy)
     : total_bytes_(kPositionNotSpecified),
       loaded_(false),
       streaming_(false),
+      single_origin_(true),
       bridge_factory_(bridge_factory),
       loader_(NULL),
       network_activity_(false),
@@ -559,6 +562,8 @@ BufferedDataSource::BufferedDataSource(
       stop_signal_received_(false),
       stopped_on_render_loop_(false),
       media_is_paused_(true) {
+  if (proxy)
+    proxy->SetDataSource(this);
 }
 
 BufferedDataSource::~BufferedDataSource() {
@@ -620,6 +625,7 @@ void BufferedDataSource::Stop(media::Fil
     callback->Run();
     delete callback;
   }
+
   render_loop_->PostTask(FROM_HERE,
       NewRunnableMethod(this, &BufferedDataSource::CleanupTask));
 }
@@ -652,6 +658,26 @@ bool BufferedDataSource::IsStreaming() {
   return streaming_;
 }
 
+bool BufferedDataSource::HasSingleOrigin() {
+  DCHECK(MessageLoop::current() == render_loop_);
+  return single_origin_;
+}
+
+
+void BufferedDataSource::Abort() {
+  DCHECK(MessageLoop::current() == render_loop_);
+
+  // If we are told to abort, immediately return from any pending read
+  // with an error.
+  if (read_callback_.get()) {
+    {
+      AutoLock auto_lock(lock_);
+      DoneRead_Locked(net::ERR_FAILED);
+    }
+    CleanupTask();
+  }
+}
+
 /////////////////////////////////////////////////////////////////////////////
 // BufferedDataSource, render thread tasks
 void BufferedDataSource::InitializeTask() {
@@ -717,7 +743,10 @@ void BufferedDataSource::ReadTask(
 
 void BufferedDataSource::CleanupTask() {
   DCHECK(MessageLoop::current() == render_loop_);
-  DCHECK(!stopped_on_render_loop_);
+
+  // If we have already stopped, do nothing.
+  if (stopped_on_render_loop_)
+    return;
 
   // Stop the watch dog.
   watch_dog_timer_.Stop();
@@ -862,6 +891,9 @@ void BufferedDataSource::HttpInitialStar
   DCHECK(MessageLoop::current() == render_loop_);
   DCHECK(loader_.get());
 
+  // Check if the request ended up at a different origin via redirect.
+  single_origin_ = url_.GetOrigin() == loader_->url().GetOrigin();
+
   int64 instance_size = loader_->instance_size();
   bool partial_response = loader_->partial_response();
   bool success = error == net::OK;
@@ -915,6 +947,9 @@ void BufferedDataSource::NonHttpInitialS
   DCHECK(MessageLoop::current() == render_loop_);
   DCHECK(loader_.get());
 
+  // Check if the request ended up at a different origin via redirect.
+  single_origin_ = url_.GetOrigin() == loader_->url().GetOrigin();
+
   int64 instance_size = loader_->instance_size();
   bool success = error == net::OK && instance_size != kPositionNotSpecified;
 
--- a/src/webkit/glue/media/buffered_data_source.h
+++ b/src/webkit/glue/media/buffered_data_source.h
@@ -23,6 +23,8 @@
 #include "net/base/completion_callback.h"
 #include "net/base/file_stream.h"
 #include "webkit/glue/media/media_resource_loader_bridge_factory.h"
+#include "webkit/glue/media/web_data_source.h"
+#include "webkit/glue/webmediaplayer_impl.h"
 
 namespace webkit_glue {
 /////////////////////////////////////////////////////////////////////////////
@@ -107,6 +109,9 @@ class BufferedResourceLoader :
   // Returns true if network is currently active.
   virtual bool network_activity() { return !completed_ && !deferred_; }
 
+  // Returns resulting URL.
+  virtual const GURL& url() { return url_; }
+
   /////////////////////////////////////////////////////////////////////////////
   // webkit_glue::ResourceLoaderBridge::Peer implementations.
   virtual void OnUploadProgress(uint64 position, uint64 size) {}
@@ -211,18 +216,20 @@ class BufferedResourceLoader :
   DISALLOW_COPY_AND_ASSIGN(BufferedResourceLoader);
 };
 
-class BufferedDataSource : public media::DataSource {
+class BufferedDataSource : public WebDataSource {
  public:
   // Methods called from pipeline thread
   // Static methods for creating this class.
   static media::FilterFactory* CreateFactory(
       MessageLoop* message_loop,
-      webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory) {
-    return new media::FilterFactoryImpl2<
+      webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory,
+      webkit_glue::WebMediaPlayerImpl::Proxy* proxy) {
+    return new media::FilterFactoryImpl3<
         BufferedDataSource,
         MessageLoop*,
-        webkit_glue::MediaResourceLoaderBridgeFactory*>(
-        message_loop, bridge_factory);
+        webkit_glue::MediaResourceLoaderBridgeFactory*,
+        webkit_glue::WebMediaPlayerImpl::Proxy*>(
+        message_loop, bridge_factory, proxy);
   }
 
   // media::FilterFactoryImpl2 implementation.
@@ -247,10 +254,16 @@ class BufferedDataSource : public media:
     return media_format_;
   }
 
+  virtual bool HasSingleOrigin();
+
+  // webkit_glue::WebDataSource implementation.
+  virtual void Abort();
+
  protected:
   BufferedDataSource(
       MessageLoop* render_loop,
-      webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory);
+      webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory,
+      webkit_glue::WebMediaPlayerImpl::Proxy* proxy);
   virtual ~BufferedDataSource();
 
   // A factory method to create a BufferedResourceLoader based on the read
@@ -265,10 +278,11 @@ class BufferedDataSource : public media:
   virtual base::TimeDelta GetTimeoutMilliseconds();
 
  private:
-  friend class media::FilterFactoryImpl2<
+  friend class media::FilterFactoryImpl3<
       BufferedDataSource,
       MessageLoop*,
-      webkit_glue::MediaResourceLoaderBridgeFactory*>;
+      webkit_glue::MediaResourceLoaderBridgeFactory*,
+      webkit_glue::WebMediaPlayerImpl::Proxy*>;
 
   // Posted to perform initialization on render thread and start resource
   // loading.
@@ -348,6 +362,9 @@ class BufferedDataSource : public media:
   // i.e. range request is not supported.
   bool streaming_;
 
+  // True if the media resource has a single origin.
+  bool single_origin_;
+
   // A factory object to produce ResourceLoaderBridge.
   scoped_ptr<webkit_glue::MediaResourceLoaderBridgeFactory> bridge_factory_;
 
--- a/src/webkit/glue/media/buffered_data_source_unittest.cc
+++ b/src/webkit/glue/media/buffered_data_source_unittest.cc
@@ -25,6 +25,7 @@ using ::testing::Invoke;
 using ::testing::InvokeWithoutArgs;
 using ::testing::NotNull;
 using ::testing::Return;
+using ::testing::ReturnRef;
 using ::testing::SetArgumentPointee;
 using ::testing::StrictMock;
 using ::testing::WithArgs;
@@ -523,6 +524,7 @@ class MockBufferedResourceLoader : publi
   MOCK_METHOD0(instance_size, int64());
   MOCK_METHOD0(partial_response, bool());
   MOCK_METHOD0(network_activity, bool());
+  MOCK_METHOD0(url, const GURL&());
   MOCK_METHOD0(GetBufferedFirstBytePosition, int64());
   MOCK_METHOD0(GetBufferedLastBytePosition, int64());
 
@@ -558,7 +560,7 @@ class MockBufferedDataSource : public Bu
  protected:
   MockBufferedDataSource(
       MessageLoop* message_loop, MediaResourceLoaderBridgeFactory* factory)
-      : BufferedDataSource(message_loop, factory) {
+      : BufferedDataSource(message_loop, factory, NULL) {
   }
 
  private:
@@ -629,10 +631,12 @@ class BufferedDataSourceTest : public te
     }
 
     StrictMock<media::MockFilterCallback> callback;
-    EXPECT_CALL(*loader_, instance_size())
-        .WillRepeatedly(Return(instance_size));
-    EXPECT_CALL(*loader_, partial_response())
-        .WillRepeatedly(Return(partial_response));
+    ON_CALL(*loader_, instance_size())
+        .WillByDefault(Return(instance_size));
+    ON_CALL(*loader_, partial_response())
+        .WillByDefault(Return(partial_response));
+    ON_CALL(*loader_, url())
+        .WillByDefault(ReturnRef(gurl_));
     if (error == net::OK) {
       // Expected loaded or not.
       EXPECT_CALL(host_, SetLoaded(loaded));
@@ -730,6 +734,23 @@ class BufferedDataSourceTest : public te
               memcmp(buffer_, data_ + static_cast<int>(position), read_size));
   }
 
+  void ReadDataSourceHang(int64 position, int size) {
+    EXPECT_TRUE(loader_);
+
+    // Expect a call to read, but the call never returns.
+    EXPECT_CALL(*loader_, Read(position, size, NotNull(), NotNull()));
+    data_source_->Read(
+        position, size, buffer_,
+        NewCallback(this, &BufferedDataSourceTest::ReadCallback));
+    message_loop_->RunAllPending();
+
+    // Now expect the read to return after aborting the data source.
+    EXPECT_CALL(*this, ReadCallback(_));
+    EXPECT_CALL(*loader_, Stop());
+    data_source_->Abort();
+    message_loop_->RunAllPending();
+  }
+
   void ReadDataSourceMiss(int64 position, int size) {
     EXPECT_TRUE(loader_);
 
@@ -912,6 +933,11 @@ TEST_F(BufferedDataSourceTest, ReadCache
   StopDataSource();
 }
 
+TEST_F(BufferedDataSourceTest, ReadHang) {
+  InitializeDataSource(kHttpUrl, net::OK, true, 25, LOADING);
+  ReadDataSourceHang(10, 10);
+}
+
 TEST_F(BufferedDataSourceTest, ReadFailed) {
   InitializeDataSource(kHttpUrl, net::OK, true, 1024, LOADING);
   ReadDataSourceHit(10, 10, 10);
--- a/src/webkit/glue/media/simple_data_source.cc
+++ b/src/webkit/glue/media/simple_data_source.cc
@@ -47,6 +47,7 @@ SimpleDataSource::SimpleDataSource(
     : render_loop_(render_loop),
       bridge_factory_(bridge_factory),
       size_(-1),
+      single_origin_(true),
       state_(UNINITIALIZED) {
   DCHECK(render_loop);
 }
@@ -129,7 +130,9 @@ bool SimpleDataSource::OnReceivedRedirec
     const webkit_glue::ResourceLoaderBridge::ResponseInfo& info,
     bool* has_new_first_party_for_cookies,
     GURL* new_first_party_for_cookies) {
-  SetURL(new_url);
+  DCHECK(MessageLoop::current() == render_loop_);
+  single_origin_ = url_.GetOrigin() == new_url.GetOrigin();
+
   // TODO(wtc): should we return a new first party for cookies URL?
   *has_new_first_party_for_cookies = false;
   return true;
@@ -138,15 +141,18 @@ bool SimpleDataSource::OnReceivedRedirec
 void SimpleDataSource::OnReceivedResponse(
     const webkit_glue::ResourceLoaderBridge::ResponseInfo& info,
     bool content_filtered) {
+  DCHECK(MessageLoop::current() == render_loop_);
   size_ = info.content_length;
 }
 
 void SimpleDataSource::OnReceivedData(const char* data, int len) {
+  DCHECK(MessageLoop::current() == render_loop_);
   data_.append(data, len);
 }
 
 void SimpleDataSource::OnCompletedRequest(const URLRequestStatus& status,
                                           const std::string& security_info) {
+  DCHECK(MessageLoop::current() == render_loop_);
   AutoLock auto_lock(lock_);
   // It's possible this gets called after Stop(), in which case |host_| is no
   // longer valid.
@@ -173,6 +179,16 @@ GURL SimpleDataSource::GetURLForDebuggin
   return url_;
 }
 
+bool SimpleDataSource::HasSingleOrigin() {
+  DCHECK(MessageLoop::current() == render_loop_);
+  return single_origin_;
+}
+
+void SimpleDataSource::Abort() {
+  DCHECK(MessageLoop::current() == render_loop_);
+  NOTIMPLEMENTED();
+}
+
 void SimpleDataSource::SetURL(const GURL& url) {
   url_ = url;
   media_format_.Clear();
@@ -182,8 +198,8 @@ void SimpleDataSource::SetURL(const GURL
 }
 
 void SimpleDataSource::StartTask() {
-  AutoLock auto_lock(lock_);
   DCHECK(MessageLoop::current() == render_loop_);
+  AutoLock auto_lock(lock_);
 
   // We may have stopped.
   if (state_ == STOPPED)
@@ -208,6 +224,7 @@ void SimpleDataSource::StartTask() {
 }
 
 void SimpleDataSource::CancelTask() {
+  DCHECK(MessageLoop::current() == render_loop_);
   AutoLock auto_lock(lock_);
   DCHECK_EQ(state_, STOPPED);
 
--- a/src/webkit/glue/media/simple_data_source.h
+++ b/src/webkit/glue/media/simple_data_source.h
@@ -66,6 +66,10 @@ class SimpleDataSource : public media::D
                                   const std::string& security_info);
   virtual GURL GetURLForDebugging() const;
 
+  // webkit_glue::WebDataSource implementation.
+  virtual bool HasSingleOrigin();
+  virtual void Abort();
+
  private:
   friend class media::FilterFactoryImpl2<
       SimpleDataSource,
@@ -101,6 +105,7 @@ class SimpleDataSource : public media::D
   GURL url_;
   std::string data_;
   int64 size_;
+  bool single_origin_;
 
   // Simple state tracking variable.
   enum State {
--- a/src/webkit/glue/webmediaplayer_impl.cc
+++ b/src/webkit/glue/webmediaplayer_impl.cc
@@ -19,6 +19,9 @@
 #include "third_party/WebKit/WebKit/chromium/public/WebRect.h"
 #include "third_party/WebKit/WebKit/chromium/public/WebSize.h"
 #include "third_party/WebKit/WebKit/chromium/public/WebURL.h"
+#include "webkit/glue/media/buffered_data_source.h"
+#include "webkit/glue/media/media_resource_loader_bridge_factory.h"
+#include "webkit/glue/media/simple_data_source.h"
 #include "webkit/glue/media/video_renderer_impl.h"
 #include "webkit/glue/media/web_video_renderer.h"
 
@@ -82,6 +85,10 @@ void WebMediaPlayerImpl::Proxy::Repaint(
   }
 }
 
+void WebMediaPlayerImpl::Proxy::SetDataSource(WebDataSource* data_source) {
+  data_source_ = data_source;
+}
+
 void WebMediaPlayerImpl::Proxy::SetVideoRenderer(
     WebVideoRenderer* video_renderer) {
   video_renderer_ = video_renderer;
@@ -102,10 +109,26 @@ void WebMediaPlayerImpl::Proxy::SetSize(
   }
 }
 
+bool WebMediaPlayerImpl::Proxy::HasSingleOrigin() {
+  DCHECK(MessageLoop::current() == render_loop_);
+  if (data_source_) {
+    return data_source_->HasSingleOrigin();
+  }
+  return true;
+}
+
+void WebMediaPlayerImpl::Proxy::AbortDataSource() {
+  DCHECK(MessageLoop::current() == render_loop_);
+  if (data_source_) {
+    data_source_->Abort();
+  }
+}
+
 void WebMediaPlayerImpl::Proxy::Detach() {
   DCHECK(MessageLoop::current() == render_loop_);
   webmediaplayer_ = NULL;
   video_renderer_ = NULL;
+  data_source_ = NULL;
 }
 
 void WebMediaPlayerImpl::Proxy::PipelineInitializationCallback() {
@@ -183,10 +206,12 @@ void WebMediaPlayerImpl::Proxy::NetworkE
 /////////////////////////////////////////////////////////////////////////////
 // WebMediaPlayerImpl implementation
 
-WebMediaPlayerImpl::WebMediaPlayerImpl(WebKit::WebMediaPlayerClient* client,
-                                       media::FilterFactoryCollection* factory,
-                                       WebVideoRendererFactoryFactory*
-                                           video_renderer_factory)
+WebMediaPlayerImpl::WebMediaPlayerImpl(
+    WebKit::WebMediaPlayerClient* client,
+    media::FilterFactoryCollection* factory,
+    MediaResourceLoaderBridgeFactory* bridge_factory,
+    bool use_simple_data_source,
+    WebVideoRendererFactoryFactory* video_renderer_factory)
     : network_state_(WebKit::WebMediaPlayer::Empty),
       ready_state_(WebKit::WebMediaPlayer::HaveNothing),
       main_loop_(NULL),
@@ -226,6 +251,23 @@ WebMediaPlayerImpl::WebMediaPlayerImpl(W
   pipeline_->SetNetworkEventCallback(NewCallback(proxy_.get(),
       &WebMediaPlayerImpl::Proxy::NetworkEventCallback));
 
+  // A simple data source that keeps all data in memory.
+  media::FilterFactory* simple_data_source_factory =
+      webkit_glue::SimpleDataSource::CreateFactory(MessageLoop::current(),
+                                                   bridge_factory);
+  // A sophisticated data source that does memory caching.
+  media::FilterFactory* buffered_data_source_factory =
+      webkit_glue::BufferedDataSource::CreateFactory(MessageLoop::current(),
+                                                     bridge_factory,
+                                                     proxy_);
+  if (use_simple_data_source) {
+    factory->AddFactory(simple_data_source_factory);
+    factory->AddFactory(buffered_data_source_factory);
+  } else {
+    factory->AddFactory(buffered_data_source_factory);
+    factory->AddFactory(simple_data_source_factory);
+  }
+
   // Add in the default filter factories.
   filter_factory_->AddFactory(media::FFmpegDemuxer::CreateFilterFactory());
   filter_factory_->AddFactory(media::FFmpegAudioDecoder::CreateFactory());
@@ -549,9 +591,8 @@ void WebMediaPlayerImpl::paint(WebCanvas
 }
 
 bool WebMediaPlayerImpl::hasSingleSecurityOrigin() const {
-  // TODO(scherkus): we'll need to do something smarter here if/when we start to
-  // support formats that contain references to external resources (i.e., MP4s
-  // containing links to other MP4s).  See http://crbug.com/25432
+  if (proxy_)
+    return proxy_->HasSingleOrigin();
   return true;
 }
 
@@ -694,6 +735,11 @@ void WebMediaPlayerImpl::SetReadyState(
 void WebMediaPlayerImpl::Destroy() {
   DCHECK(MessageLoop::current() == main_loop_);
 
+  // Tell the data source to abort any pending reads so that the pipeline is
+  // not blocked when issuing stop commands to the other filters.
+  if (proxy_)
+    proxy_->AbortDataSource();
+
   // Make sure to kill the pipeline so there's no more media threads running.
   // Note: stopping the pipeline might block for a long time.
   pipeline_->Stop(NewCallback(this,
--- a/src/webkit/glue/webmediaplayer_impl.h
+++ b/src/webkit/glue/webmediaplayer_impl.h
@@ -76,6 +76,8 @@ class FilterFactoryCollection;
 
 namespace webkit_glue {
 
+class MediaResourceLoaderBridgeFactory;
+class WebDataSource;
 class WebVideoRenderer;
 class WebVideoRendererFactoryFactory;
 
@@ -98,11 +100,14 @@ class WebMediaPlayerImpl : public WebKit
     // Public methods called from the video renderer.
     void Repaint();
     void SetVideoRenderer(WebVideoRenderer* video_renderer);
+    void SetDataSource(WebDataSource* data_source);
 
     // Public methods called from WebMediaPlayerImpl.
     void Paint(skia::PlatformCanvas* canvas, const gfx::Rect& dest_rect);
     void SetSize(const gfx::Rect& rect);
     void Detach();
+    void AbortDataSource();
+    bool HasSingleOrigin();
 
     // Public methods called from the pipeline via callback issued by
     // WebMediaPlayerImpl.
@@ -141,6 +146,7 @@ class WebMediaPlayerImpl : public WebKit
     // The render message loop where WebKit lives.
     MessageLoop* render_loop_;
     WebMediaPlayerImpl* webmediaplayer_;
+    scoped_refptr<WebDataSource> data_source_;
     scoped_refptr<WebVideoRenderer> video_renderer_;
 
     Lock lock_;
@@ -172,6 +178,8 @@ class WebMediaPlayerImpl : public WebKit
   // a subclass of WebVideoRenderer.  Is deleted by WebMediaPlayerImpl.
   WebMediaPlayerImpl(WebKit::WebMediaPlayerClient* client,
                      media::FilterFactoryCollection* factory,
+                     MediaResourceLoaderBridgeFactory* bridge_factory,
+                     bool use_simple_data_source,
                      WebVideoRendererFactoryFactory* video_renderer_factory);
   virtual ~WebMediaPlayerImpl();
 
--- a/src/chrome/renderer/render_view.cc
+++ b/src/chrome/renderer/render_view.cc
@@ -2270,22 +2270,6 @@ WebMediaPlayer* RenderView::createMediaP
           appcache_host ? appcache_host->host_id() : appcache::kNoHostId,
           routing_id());
 
-  // A simple data source that keeps all data in memory.
-  media::FilterFactory* simple_data_source_factory =
-      webkit_glue::SimpleDataSource::CreateFactory(MessageLoop::current(),
-                                                   bridge_factory);
-  // A sophisticated data source that does memory caching.
-  media::FilterFactory* buffered_data_source_factory =
-      webkit_glue::BufferedDataSource::CreateFactory(MessageLoop::current(),
-                                                     bridge_factory);
-  if (cmd_line->HasSwitch(switches::kSimpleDataSource)) {
-    factory->AddFactory(simple_data_source_factory);
-    factory->AddFactory(buffered_data_source_factory);
-  } else {
-    factory->AddFactory(buffered_data_source_factory);
-    factory->AddFactory(simple_data_source_factory);
-  }
-
   webkit_glue::WebVideoRendererFactoryFactory* factory_factory = NULL;
   if (cmd_line->HasSwitch(switches::kEnableVideoLayering)) {
     factory_factory = new IPCVideoRenderer::FactoryFactory(routing_id_);
@@ -2295,7 +2279,9 @@ WebMediaPlayer* RenderView::createMediaP
         new webkit_glue::VideoRendererImpl::FactoryFactory(pts_logging);
   }
 
-  return new webkit_glue::WebMediaPlayerImpl(client, factory, factory_factory);
+  return new webkit_glue::WebMediaPlayerImpl(
+      client, factory, bridge_factory,
+      cmd_line->HasSwitch(switches::kSimpleDataSource), factory_factory);
 }
 
 WebApplicationCacheHost* RenderView::createApplicationCacheHost(
--- a/src/webkit/glue/webkit_glue.gypi
+++ b/src/webkit/glue/webkit_glue.gypi
@@ -151,6 +151,8 @@
         'media/simple_data_source.h',
         'media/video_renderer_impl.cc',
         'media/video_renderer_impl.h',
+        'media/web_data_source.cc',
+        'media/web_data_source.h',
         'media/web_video_renderer.h',
         'plugins/carbon_plugin_window_tracker_mac.h',
         'plugins/carbon_plugin_window_tracker_mac.cc',
--- a/src/webkit/support/webkit_support.cc
+++ b/src/webkit/support/webkit_support.cc
@@ -205,18 +205,9 @@ WebKit::WebMediaPlayer* CreateMediaPlaye
           base::GetCurrentProcId(),
           appcache_host ? appcache_host->host_id() : appcache::kNoHostId,
           0);
-  // A simple data source that keeps all data in memory.
-  media::FilterFactory* simple_data_source_factory =
-      webkit_glue::SimpleDataSource::CreateFactory(MessageLoop::current(),
-                                                   bridge_factory);
-  // A sophisticated data source that does memory caching.
-  media::FilterFactory* buffered_data_source_factory =
-      webkit_glue::BufferedDataSource::CreateFactory(MessageLoop::current(),
-                                                     bridge_factory);
-  factory->AddFactory(buffered_data_source_factory);
-  factory->AddFactory(simple_data_source_factory);
+
   return new webkit_glue::WebMediaPlayerImpl(
-      client, factory,
+      client, factory, bridge_factory, false,
       new webkit_glue::VideoRendererImpl::FactoryFactory(false));
 }
 
--- a/src/webkit/tools/test_shell/test_webview_delegate.cc
+++ b/src/webkit/tools/test_shell/test_webview_delegate.cc
@@ -710,18 +710,9 @@ WebMediaPlayer* TestWebViewDelegate::cre
           base::GetCurrentProcId(),
           appcache_host ? appcache_host->host_id() : appcache::kNoHostId,
           0);
-  // A simple data source that keeps all data in memory.
-  media::FilterFactory* simple_data_source_factory =
-      webkit_glue::SimpleDataSource::CreateFactory(MessageLoop::current(),
-                                                   bridge_factory);
-  // A sophisticated data source that does memory caching.
-  media::FilterFactory* buffered_data_source_factory =
-      webkit_glue::BufferedDataSource::CreateFactory(MessageLoop::current(),
-                                                     bridge_factory);
-  factory->AddFactory(buffered_data_source_factory);
-  factory->AddFactory(simple_data_source_factory);
+
   return new webkit_glue::WebMediaPlayerImpl(
-      client, factory,
+      client, factory, bridge_factory, false,
       new webkit_glue::VideoRendererImpl::FactoryFactory(false));
 }
 
--- /dev/null
+++ b/src/webkit/glue/media/web_data_source.cc
@@ -0,0 +1,17 @@
+// Copyright (c) 2010 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.
+
+#include "media/base/filters.h"
+#include "webkit/glue/media/web_data_source.h"
+
+namespace webkit_glue {
+
+WebDataSource::WebDataSource()
+    : media::DataSource() {
+}
+
+WebDataSource::~WebDataSource() {
+}
+
+}  // namespace webkit_glue
--- /dev/null
+++ b/src/webkit/glue/media/web_data_source.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2010 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 WEBKIT_GLUE_MEDIA_WEB_DATA_SOURCE_H_
+#define WEBKIT_GLUE_MEDIA_WEB_DATA_SOURCE_H_
+
+#include "media/base/filters.h"
+
+namespace webkit_glue {
+
+// An interface that allows WebMediaPlayerImpl::Proxy to communicate with the
+// DataSource in the pipeline.
+class WebDataSource : public media::DataSource {
+ public:
+  WebDataSource();
+  virtual ~WebDataSource();
+
+  // Returns true if the media resource has a single origin, false otherwise.
+  //
+  // Method called on the render thread.
+  virtual bool HasSingleOrigin() = 0;
+
+  // This method is used to unblock any read calls that would cause the
+  // media pipeline to stall.
+  //
+  // Method called on the render thread.
+  virtual void Abort() = 0;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(WebDataSource);
+};
+
+}  // namespace webkit_glue
+
+#endif  // WEBKIT_GLUE_MEDIA_WEB_DATA_SOURCE_H_
