Simplified frame rate control in the chromoting host.

Insted of keeping semi-fixed frame rate, now capturing rate is controlled
by how fast we can send data to the client. Capturing of frame n is
started only after frame n-2 is sent (while n-1 is being encoded). This
guarantees that we don't clog the video channel buffers, and that we start
capturing only if we know that the frame will not need to wait for too long
in the buffer.

TEST=None
BUG=None

Review URL: http://codereview.chromium.org/5634002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@68688 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/remoting/protocol/buffered_socket_writer.cc b/remoting/protocol/buffered_socket_writer.cc
index 0cf39bc..11b8395 100644
--- a/remoting/protocol/buffered_socket_writer.cc
+++ b/remoting/protocol/buffered_socket_writer.cc
@@ -5,11 +5,34 @@
 #include "remoting/protocol/buffered_socket_writer.h"
 
 #include "base/message_loop.h"
+#include "base/stl_util-inl.h"
 #include "net/base/net_errors.h"
 
 namespace remoting {
 namespace protocol {
 
+class BufferedSocketWriterBase::PendingPacket {
+ public:
+  PendingPacket(scoped_refptr<net::IOBufferWithSize> data, Task* done_task)
+      : data_(data),
+        done_task_(done_task) {
+  }
+  ~PendingPacket() {
+    if (done_task_.get())
+      done_task_->Run();
+  }
+
+  net::IOBufferWithSize* data() {
+    return data_;
+  }
+
+ private:
+  scoped_refptr<net::IOBufferWithSize> data_;
+  scoped_ptr<Task> done_task_;
+
+  DISALLOW_COPY_AND_ASSIGN(PendingPacket);
+};
+
 BufferedSocketWriterBase::BufferedSocketWriterBase()
     : buffer_size_(0),
       socket_(NULL),
@@ -32,11 +55,11 @@
 }
 
 bool BufferedSocketWriterBase::Write(
-    scoped_refptr<net::IOBufferWithSize> data) {
+    scoped_refptr<net::IOBufferWithSize> data, Task* done_task) {
   AutoLock auto_lock(lock_);
   if (!socket_)
     return false;
-  queue_.push(data);
+  queue_.push_back(new PendingPacket(data, done_task));
   buffer_size_ += data->size();
   message_loop_->PostTask(
       FROM_HERE, NewRunnableMethod(this, &BufferedSocketWriterBase::DoWrite));
@@ -112,9 +135,7 @@
 void BufferedSocketWriterBase::HandleError(int result) {
   AutoLock auto_lock(lock_);
   closed_ = true;
-  while (!queue_.empty()) {
-    queue_.pop();
-  }
+  STLDeleteElements(&queue_);
 
   // Notify subclass that an error is received.
   OnError_Locked(result);
@@ -135,19 +156,27 @@
   closed_ = true;
 }
 
+void BufferedSocketWriterBase::PopQueue() {
+  // This also calls |done_task|.
+  delete queue_.front();
+  queue_.pop_front();
+}
+
 BufferedSocketWriter::BufferedSocketWriter() { }
-BufferedSocketWriter::~BufferedSocketWriter() { }
+
+BufferedSocketWriter::~BufferedSocketWriter() {
+  STLDeleteElements(&queue_);
+}
 
 void BufferedSocketWriter::GetNextPacket_Locked(
     net::IOBuffer** buffer, int* size) {
-  while (!current_buf_ || current_buf_->BytesRemaining() == 0) {
+  if (!current_buf_) {
     if (queue_.empty()) {
       *buffer = NULL;
       return;  // Nothing to write.
     }
-    current_buf_ =
-        new net::DrainableIOBuffer(queue_.front(), queue_.front()->size());
-    queue_.pop();
+    current_buf_ = new net::DrainableIOBuffer(
+        queue_.front()->data(), queue_.front()->data()->size());
   }
 
   *buffer = current_buf_;
@@ -157,6 +186,11 @@
 void BufferedSocketWriter::AdvanceBufferPosition_Locked(int written) {
   buffer_size_ -= written;
   current_buf_->DidConsume(written);
+
+  if (current_buf_->BytesRemaining() == 0) {
+    PopQueue();
+    current_buf_ = NULL;
+  }
 }
 
 void BufferedSocketWriter::OnError_Locked(int result) {
@@ -172,14 +206,14 @@
     *buffer = NULL;
     return;  // Nothing to write.
   }
-  *buffer = queue_.front();
-  *size = queue_.front()->size();
+  *buffer = queue_.front()->data();
+  *size = queue_.front()->data()->size();
 }
 
 void BufferedDatagramWriter::AdvanceBufferPosition_Locked(int written) {
-  DCHECK_EQ(written, queue_.front()->size());
-  buffer_size_ -= queue_.front()->size();
-  queue_.pop();
+  DCHECK_EQ(written, queue_.front()->data()->size());
+  buffer_size_ -= queue_.front()->data()->size();
+  PopQueue();
 }
 
 void BufferedDatagramWriter::OnError_Locked(int result) {