Upstream version 10.38.222.0
[platform/framework/web/crosswalk.git] / src / content / renderer / media / buffered_data_source.cc
index 861111e..e05ec43 100644 (file)
@@ -7,10 +7,11 @@
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/message_loop/message_loop_proxy.h"
+#include "content/public/common/url_constants.h"
 #include "media/base/media_log.h"
 #include "net/base/net_errors.h"
 
-using WebKit::WebFrame;
+using blink::WebFrame;
 
 namespace {
 
@@ -78,15 +79,16 @@ void BufferedDataSource::ReadOperation::Run(
 }
 
 BufferedDataSource::BufferedDataSource(
+    const GURL& url,
+    BufferedResourceLoader::CORSMode cors_mode,
     const scoped_refptr<base::MessageLoopProxy>& render_loop,
     WebFrame* frame,
     media::MediaLog* media_log,
+    BufferedDataSourceHost* host,
     const DownloadingCB& downloading_cb)
-    : weak_factory_(this),
-      weak_this_(weak_factory_.GetWeakPtr()),
-      cors_mode_(BufferedResourceLoader::kUnspecified),
+    : url_(url),
+      cors_mode_(cors_mode),
       total_bytes_(kPositionNotSpecified),
-      assume_fully_buffered_(false),
       streaming_(false),
       frame_(frame),
       intermediate_read_buffer_(new uint8[kInitialReadBufferSize]),
@@ -98,7 +100,10 @@ BufferedDataSource::BufferedDataSource(
       bitrate_(0),
       playback_rate_(0.0),
       media_log_(media_log),
-      downloading_cb_(downloading_cb) {
+      host_(host),
+      downloading_cb_(downloading_cb),
+      weak_factory_(this) {
+  DCHECK(host_);
   DCHECK(!downloading_cb_.is_null());
 }
 
@@ -125,28 +130,14 @@ BufferedResourceLoader* BufferedDataSource::CreateResourceLoader(
                                     media_log_.get());
 }
 
-void BufferedDataSource::set_host(media::DataSourceHost* host) {
-  DataSource::set_host(host);
-
-  if (loader_) {
-    base::AutoLock auto_lock(lock_);
-    UpdateHostState_Locked();
-  }
-}
-
-void BufferedDataSource::Initialize(
-    const GURL& url,
-    BufferedResourceLoader::CORSMode cors_mode,
-    const InitializeCB& init_cb) {
+void BufferedDataSource::Initialize(const InitializeCB& init_cb) {
   DCHECK(render_loop_->BelongsToCurrentThread());
   DCHECK(!init_cb.is_null());
   DCHECK(!loader_.get());
-  url_ = url;
-  cors_mode_ = cors_mode;
 
   init_cb_ = init_cb;
 
-  if (url_.SchemeIs(kHttpScheme) || url_.SchemeIs(kHttpsScheme)) {
+  if (url_.SchemeIsHTTPOrHTTPS()) {
     // Do an unbounded range request starting at the beginning.  If the server
     // responds with 200 instead of 206 we'll fall back into a streaming mode.
     loader_.reset(CreateResourceLoader(0, kPositionNotSpecified));
@@ -156,13 +147,13 @@ void BufferedDataSource::Initialize(
     // we won't be served HTTP headers.
     loader_.reset(CreateResourceLoader(kPositionNotSpecified,
                                        kPositionNotSpecified));
-    assume_fully_buffered_ = true;
   }
 
+  base::WeakPtr<BufferedDataSource> weak_this = weak_factory_.GetWeakPtr();
   loader_->Start(
-      base::Bind(&BufferedDataSource::StartCallback, weak_this_),
-      base::Bind(&BufferedDataSource::LoadingStateChangedCallback, weak_this_),
-      base::Bind(&BufferedDataSource::ProgressCallback, weak_this_),
+      base::Bind(&BufferedDataSource::StartCallback, weak_this),
+      base::Bind(&BufferedDataSource::LoadingStateChangedCallback, weak_this),
+      base::Bind(&BufferedDataSource::ProgressCallback, weak_this),
       frame_);
 }
 
@@ -216,20 +207,22 @@ void BufferedDataSource::MediaIsPaused() {
 
 /////////////////////////////////////////////////////////////////////////////
 // media::DataSource implementation.
-void BufferedDataSource::Stop(const base::Closure& closure) {
+void BufferedDataSource::Stop() {
   {
     base::AutoLock auto_lock(lock_);
     StopInternal_Locked();
   }
-  closure.Run();
 
-  render_loop_->PostTask(FROM_HERE,
-      base::Bind(&BufferedDataSource::StopLoader, weak_this_));
+  render_loop_->PostTask(
+      FROM_HERE,
+      base::Bind(&BufferedDataSource::StopLoader, weak_factory_.GetWeakPtr()));
 }
 
 void BufferedDataSource::SetBitrate(int bitrate) {
-  render_loop_->PostTask(FROM_HERE, base::Bind(
-      &BufferedDataSource::SetBitrateTask, weak_this_, bitrate));
+  render_loop_->PostTask(FROM_HERE,
+                         base::Bind(&BufferedDataSource::SetBitrateTask,
+                                    weak_factory_.GetWeakPtr(),
+                                    bitrate));
 }
 
 void BufferedDataSource::Read(
@@ -250,8 +243,9 @@ void BufferedDataSource::Read(
     read_op_.reset(new ReadOperation(position, size, data, read_cb));
   }
 
-  render_loop_->PostTask(FROM_HERE, base::Bind(
-      &BufferedDataSource::ReadTask, weak_this_));
+  render_loop_->PostTask(
+      FROM_HERE,
+      base::Bind(&BufferedDataSource::ReadTask, weak_factory_.GetWeakPtr()));
 }
 
 bool BufferedDataSource::GetSize(int64* size_out) {
@@ -326,9 +320,11 @@ void BufferedDataSource::ReadInternal() {
   }
 
   // Perform the actual read with BufferedResourceLoader.
-  loader_->Read(
-      position, size, intermediate_read_buffer_.get(),
-      base::Bind(&BufferedDataSource::ReadCallback, weak_this_));
+  loader_->Read(position,
+                size,
+                intermediate_read_buffer_.get(),
+                base::Bind(&BufferedDataSource::ReadCallback,
+                           weak_factory_.GetWeakPtr()));
 }
 
 
@@ -352,12 +348,13 @@ void BufferedDataSource::StartCallback(
   // All responses must be successful. Resources that are assumed to be fully
   // buffered must have a known content length.
   bool success = status == BufferedResourceLoader::kOk &&
-      (!assume_fully_buffered_ ||
-       loader_->instance_size() != kPositionNotSpecified);
+                 (!assume_fully_buffered() ||
+                  loader_->instance_size() != kPositionNotSpecified);
 
   if (success) {
     total_bytes_ = loader_->instance_size();
-    streaming_ = !assume_fully_buffered_ &&
+    streaming_ =
+        !assume_fully_buffered() &&
         (total_bytes_ == kPositionNotSpecified || !loader_->range_supported());
 
     media_log_->SetDoubleProperty("total_bytes",
@@ -374,7 +371,12 @@ void BufferedDataSource::StartCallback(
     return;
 
   if (success) {
-    UpdateHostState_Locked();
+    if (total_bytes_ != kPositionNotSpecified) {
+      host_->SetTotalBytes(total_bytes_);
+      if (assume_fully_buffered())
+        host_->AddBufferedByteRange(0, total_bytes_);
+    }
+
     media_log_->SetBooleanProperty("single_origin", loader_->HasSingleOrigin());
     media_log_->SetBooleanProperty("passed_cors_access_check",
                                    loader_->DidPassCORSAccessCheck());
@@ -431,11 +433,13 @@ void BufferedDataSource::ReadCallback(
       // end of the resource.
       loader_.reset(CreateResourceLoader(
           read_op_->position(), kPositionNotSpecified));
+
+      base::WeakPtr<BufferedDataSource> weak_this = weak_factory_.GetWeakPtr();
       loader_->Start(
-          base::Bind(&BufferedDataSource::PartialReadStartCallback, weak_this_),
+          base::Bind(&BufferedDataSource::PartialReadStartCallback, weak_this),
           base::Bind(&BufferedDataSource::LoadingStateChangedCallback,
-                     weak_this_),
-          base::Bind(&BufferedDataSource::ProgressCallback, weak_this_),
+                     weak_this),
+          base::Bind(&BufferedDataSource::ProgressCallback, weak_this),
           frame_);
       return;
     }
@@ -452,10 +456,10 @@ void BufferedDataSource::ReadCallback(
     // fail like they would if we had known the file size at the beginning.
     total_bytes_ = loader_->instance_size();
 
-    if (host() && total_bytes_ != kPositionNotSpecified) {
-      host()->SetTotalBytes(total_bytes_);
-      host()->AddBufferedByteRange(loader_->first_byte_position(),
-                                   total_bytes_);
+    if (total_bytes_ != kPositionNotSpecified) {
+      host_->SetTotalBytes(total_bytes_);
+      host_->AddBufferedByteRange(loader_->first_byte_position(),
+                                  total_bytes_);
     }
   }
   ReadOperation::Run(read_op_.Pass(), bytes_read);
@@ -465,7 +469,7 @@ void BufferedDataSource::LoadingStateChangedCallback(
     BufferedResourceLoader::LoadingState state) {
   DCHECK(render_loop_->BelongsToCurrentThread());
 
-  if (assume_fully_buffered_)
+  if (assume_fully_buffered())
     return;
 
   bool is_downloading_data;
@@ -493,7 +497,7 @@ void BufferedDataSource::LoadingStateChangedCallback(
 void BufferedDataSource::ProgressCallback(int64 position) {
   DCHECK(render_loop_->BelongsToCurrentThread());
 
-  if (assume_fully_buffered_)
+  if (assume_fully_buffered())
     return;
 
   // TODO(scherkus): we shouldn't have to lock to signal host(), see
@@ -502,42 +506,13 @@ void BufferedDataSource::ProgressCallback(int64 position) {
   if (stop_signal_received_)
     return;
 
-  ReportOrQueueBufferedBytes(loader_->first_byte_position(), position);
-}
-
-void BufferedDataSource::ReportOrQueueBufferedBytes(int64 start, int64 end) {
-  if (host())
-    host()->AddBufferedByteRange(start, end);
-  else
-    queued_buffered_byte_ranges_.Add(start, end);
-}
-
-void BufferedDataSource::UpdateHostState_Locked() {
-  lock_.AssertAcquired();
-
-  if (!host())
-    return;
-
-  for (size_t i = 0; i < queued_buffered_byte_ranges_.size(); ++i) {
-    host()->AddBufferedByteRange(queued_buffered_byte_ranges_.start(i),
-                                 queued_buffered_byte_ranges_.end(i));
-  }
-  queued_buffered_byte_ranges_.clear();
-
-  if (total_bytes_ == kPositionNotSpecified)
-    return;
-
-  host()->SetTotalBytes(total_bytes_);
-
-  if (assume_fully_buffered_)
-    host()->AddBufferedByteRange(0, total_bytes_);
+  host_->AddBufferedByteRange(loader_->first_byte_position(), position);
 }
 
 void BufferedDataSource::UpdateDeferStrategy(bool paused) {
-  // 200 responses end up not being reused to satisfy future range requests,
-  // and we don't want to get too far ahead of the read-head (and thus require
-  // a restart), so keep to the thresholds.
-  if (!loader_->range_supported()) {
+  // No need to aggressively buffer when we are assuming the resource is fully
+  // buffered.
+  if (assume_fully_buffered()) {
     loader_->UpdateDeferStrategy(BufferedResourceLoader::kCapacityDefer);
     return;
   }
@@ -546,14 +521,15 @@ void BufferedDataSource::UpdateDeferStrategy(bool paused) {
   // and we're paused, then try to load as much as possible (the loader will
   // fall back to kCapacityDefer if it knows the current response won't be
   // useful from the cache in the future).
-  if (media_has_played_ && paused) {
+  if (media_has_played_ && paused && loader_->range_supported()) {
     loader_->UpdateDeferStrategy(BufferedResourceLoader::kNeverDefer);
     return;
   }
 
-  // If media is currently playing or the page indicated preload=auto,
-  // use threshold strategy to enable/disable deferring when the buffer
-  // is full/depleted.
+  // If media is currently playing or the page indicated preload=auto or the
+  // the server does not support the byte range request or we do not want to go
+  // too far ahead of the read head, use threshold strategy to enable/disable
+  // deferring when the buffer is full/depleted.
   loader_->UpdateDeferStrategy(BufferedResourceLoader::kCapacityDefer);
 }