diff --git a/base/task.cc b/base/task.cc
index d33f3e1a884fa..e4da5474a0098 100644
--- a/base/task.cc
+++ b/base/task.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
 
@@ -15,3 +15,23 @@ CancelableTask::CancelableTask() {
 
 CancelableTask::~CancelableTask() {
 }
+
+namespace base {
+
+ScopedTaskRunner::ScopedTaskRunner(Task* task) : task_(task) {
+}
+
+ScopedTaskRunner::~ScopedTaskRunner() {
+  if (task_) {
+    task_->Run();
+    delete task_;
+  }
+}
+
+Task* ScopedTaskRunner::Release() {
+  Task* tmp = task_;
+  task_ = NULL;
+  return tmp;
+}
+
+}  // namespace base
diff --git a/base/task.h b/base/task.h
index b698576ef899e..ae47f32615b1b 100644
--- a/base/task.h
+++ b/base/task.h
@@ -546,4 +546,24 @@ inline Task* NewRunnableFunction(Function function, const A& a, const B& b,
       function, MakeTuple(a, b, c, d, e, f, g, h));
 }
 
+namespace base {
+
+// ScopedTaskRunner is akin to scoped_ptr for Tasks.  It ensures that the Task
+// is executed and deleted no matter how the current scope exits.
+class BASE_API ScopedTaskRunner {
+ public:
+  // Takes ownership of the task.
+  explicit ScopedTaskRunner(Task* task);
+  ~ScopedTaskRunner();
+
+  Task* Release();
+
+ private:
+  Task* task_;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedTaskRunner);
+};
+
+}  // namespace base
+
 #endif  // BASE_TASK_H_
diff --git a/base/task_unittest.cc b/base/task_unittest.cc
index 25c201d267b80..e0cb659cf094c 100644
--- a/base/task_unittest.cc
+++ b/base/task_unittest.cc
@@ -49,4 +49,62 @@ TEST(TaskTest, TestCancelInDestructor) {
   delete cancelable_task;
 }
 
+class DoneTask : public Task {
+ public:
+  DoneTask(int* run_count, bool* was_deleted)
+      : run_count_(run_count), was_deleted_(was_deleted) {
+  }
+  virtual ~DoneTask() {
+    *was_deleted_ = true;
+  }
+
+  virtual void Run() {
+    ++(*run_count_);
+  }
+
+  int* run_count_;
+  bool* was_deleted_;
+};
+
+TEST(TaskTest, TestScopedTaskRunnerExitScope) {
+  int run_count = 0;
+  bool was_deleted = false;
+  {
+    base::ScopedTaskRunner runner(new DoneTask(&run_count, &was_deleted));
+    EXPECT_EQ(0, run_count);
+  }
+  EXPECT_EQ(1, run_count);
+  EXPECT_TRUE(was_deleted);
+}
+
+TEST(TaskTest, TestScopedTaskRunnerRelease) {
+  int run_count = 0;
+  bool was_deleted = false;
+  {
+    base::ScopedTaskRunner runner(new DoneTask(&run_count, &was_deleted));
+    delete runner.Release();
+    EXPECT_TRUE(was_deleted);
+  }
+  EXPECT_EQ(0, run_count);
+}
+
+TEST(TaskTest, TestScopedTaskRunnerManualRun) {
+  int run_count = 0;
+  Task* done_task = NULL;
+  bool was_deleted = false;
+  {
+    base::ScopedTaskRunner runner(new DoneTask(&run_count, &was_deleted));
+    done_task = runner.Release();
+    EXPECT_TRUE(NULL != done_task);
+    EXPECT_FALSE(was_deleted);
+    EXPECT_EQ(0, run_count);
+    done_task->Run();
+    EXPECT_FALSE(was_deleted);
+    EXPECT_EQ(1, run_count);
+  }
+  EXPECT_EQ(1, run_count);
+  delete done_task;
+  EXPECT_TRUE(was_deleted);
+}
+
 }  // namespace
diff --git a/content/renderer/media/video_capture_impl.cc b/content/renderer/media/video_capture_impl.cc
index faf4565bfcb60..da02e2fe54caf 100644
--- a/content/renderer/media/video_capture_impl.cc
+++ b/content/renderer/media/video_capture_impl.cc
@@ -381,6 +381,6 @@ void VideoCaptureImpl::AddDelegateOnIOThread() {
 }
 
 void VideoCaptureImpl::RemoveDelegateOnIOThread(Task* task) {
+  base::ScopedTaskRunner task_runner(task);
   message_filter_->RemoveDelegate(this);
-  media::AutoTaskRunner auto_runner(task);
 }
diff --git a/content/renderer/media/video_capture_impl.h b/content/renderer/media/video_capture_impl.h
index 4613e4bd4bf42..68549ef17c738 100644
--- a/content/renderer/media/video_capture_impl.h
+++ b/content/renderer/media/video_capture_impl.h
@@ -13,7 +13,6 @@
 #include <map>
 
 #include "content/renderer/video_capture_message_filter.h"
-#include "media/base/callback.h"
 #include "media/video/capture/video_capture.h"
 #include "ui/gfx/surface/transport_dib.h"
 
diff --git a/media/base/callback.cc b/media/base/callback.cc
index 484c74465449b..3daac8e229b16 100644
--- a/media/base/callback.cc
+++ b/media/base/callback.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
 
@@ -6,12 +6,6 @@
 
 namespace media {
 
-AutoTaskRunner::~AutoTaskRunner() {
-  if (task_.get()) {
-    task_->Run();
-  }
-}
-
 AutoCallbackRunner::~AutoCallbackRunner() {
   if (callback_.get()) {
     callback_->Run();
diff --git a/media/base/callback.h b/media/base/callback.h
index 460af244b0061..49488296f2a01 100644
--- a/media/base/callback.h
+++ b/media/base/callback.h
@@ -4,9 +4,9 @@
 
 // Some basic utilities for aiding in the management of Tasks and Callbacks.
 //
-// AutoTaskRunner, and its brother AutoCallbackRunner are the scoped_ptr
-// equivalents for callbacks.  They are useful for ensuring a callback is
-// executed and delete in the face of multiple return points in a function.
+// AutoCallbackRunner is akin to scoped_ptr for callbacks.  It is useful for
+// ensuring a callback is executed and delete in the face of multiple return
+// points in a function.
 //
 // TaskToCallbackAdapter converts a Task to a Callback0::Type since the two type
 // hierarchies are strangely separate.
@@ -27,23 +27,6 @@
 
 namespace media {
 
-class AutoTaskRunner {
- public:
-  // Takes ownership of the task.
-  explicit AutoTaskRunner(Task* task)
-      : task_(task) {
-  }
-
-  ~AutoTaskRunner();
-
-  Task* release() { return task_.release(); }
-
- private:
-  scoped_ptr<Task> task_;
-
-  DISALLOW_COPY_AND_ASSIGN(AutoTaskRunner);
-};
-
 class AutoCallbackRunner {
  public:
   // Takes ownership of the callback.
@@ -77,38 +60,6 @@ class TaskToCallbackAdapter : public Callback0::Type {
   DISALLOW_COPY_AND_ASSIGN(TaskToCallbackAdapter);
 };
 
-template <typename CallbackType>
-class CleanupCallback : public CallbackType {
- public:
-  explicit CleanupCallback(CallbackType* callback) : callback_(callback) {}
-
-  virtual ~CleanupCallback() {
-    for (size_t i = 0; i < run_when_done_.size(); i++) {
-      run_when_done_[i]->Run();
-      delete run_when_done_[i];
-    }
-  }
-
-  virtual void RunWithParams(const typename CallbackType::TupleType& params) {
-    callback_->RunWithParams(params);
-  }
-
-  template <typename T>
-  void DeleteWhenDone(T* ptr) {
-    RunWhenDone(new DeleteTask<T>(ptr));
-  }
-
-  void RunWhenDone(Task* ptr) {
-    run_when_done_.push_back(ptr);
-  }
-
- private:
-  scoped_ptr<CallbackType> callback_;
-  std::vector<Task*> run_when_done_;
-
-  DISALLOW_COPY_AND_ASSIGN(CleanupCallback);
-};
-
 }  // namespace media
 
 #endif  // MEDIA_BASE_CALLBACK_
diff --git a/media/filters/decoder_base.h b/media/filters/decoder_base.h
index a889e19fb1082..338b036498ed9 100644
--- a/media/filters/decoder_base.h
+++ b/media/filters/decoder_base.h
@@ -102,7 +102,7 @@ class DecoderBase : public Decoder {
   // be called from within the Filter::Stop() method prior to stopping the
   // base class.
   virtual void DoStop(Task* done_cb) {
-    AutoTaskRunner done_runner(done_cb);
+    base::ScopedTaskRunner run_done_cb(done_cb);
   }
 
   // Derived class can implement this method and perform seeking logic prior
diff --git a/media/filters/decoder_base_unittest.cc b/media/filters/decoder_base_unittest.cc
index f29bd3ad2cb10..c742f919d157c 100644
--- a/media/filters/decoder_base_unittest.cc
+++ b/media/filters/decoder_base_unittest.cc
@@ -53,7 +53,7 @@ class MockDecoderImpl : public DecoderBase<MockAudioDecoder, Buffer> {
 };
 
 ACTION(Initialize) {
-  AutoTaskRunner done_runner(arg2);
+  base::ScopedTaskRunner done_runner(arg2);
   *arg1 = true;
 }
 
diff --git a/media/filters/ffmpeg_audio_decoder.cc b/media/filters/ffmpeg_audio_decoder.cc
index 555ccfc5b13be..22c568574395c 100644
--- a/media/filters/ffmpeg_audio_decoder.cc
+++ b/media/filters/ffmpeg_audio_decoder.cc
@@ -4,7 +4,6 @@
 
 #include "media/filters/ffmpeg_audio_decoder.h"
 
-#include "media/base/callback.h"
 #include "media/base/data_buffer.h"
 #include "media/base/limits.h"
 #include "media/ffmpeg/ffmpeg_common.h"
@@ -40,7 +39,7 @@ FFmpegAudioDecoder::~FFmpegAudioDecoder() {
 void FFmpegAudioDecoder::DoInitialize(DemuxerStream* demuxer_stream,
                                       bool* success,
                                       Task* done_cb) {
-  AutoTaskRunner done_runner(done_cb);
+  base::ScopedTaskRunner done_runner(done_cb);
   *success = false;
 
   AVStream* av_stream = demuxer_stream->GetAVStream();
diff --git a/remoting/client/rectangle_update_decoder.cc b/remoting/client/rectangle_update_decoder.cc
index 5659fc5baa31c..ca7e24abd22be 100644
--- a/remoting/client/rectangle_update_decoder.cc
+++ b/remoting/client/rectangle_update_decoder.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
 
@@ -6,7 +6,6 @@
 
 #include "base/logging.h"
 #include "base/message_loop.h"
-#include "media/base/callback.h"
 #include "remoting/base/decoder.h"
 #include "remoting/base/decoder_row_based.h"
 #include "remoting/base/decoder_vp8.h"
@@ -15,7 +14,6 @@
 #include "remoting/client/frame_consumer.h"
 #include "remoting/protocol/session_config.h"
 
-using media::AutoTaskRunner;
 using remoting::protocol::ChannelConfig;
 using remoting::protocol::SessionConfig;
 
@@ -84,11 +82,11 @@ void RectangleUpdateDecoder::DecodePacket(const VideoPacket* packet,
                         done));
     return;
   }
-  AutoTaskRunner done_runner(done);
+  base::ScopedTaskRunner done_runner(done);
 
   TraceContext::tracer()->PrintString("Decode Packet called.");
 
-  AllocateFrame(packet, done_runner.release());
+  AllocateFrame(packet, done_runner.Release());
 }
 
 void RectangleUpdateDecoder::AllocateFrame(const VideoPacket* packet,
@@ -100,7 +98,7 @@ void RectangleUpdateDecoder::AllocateFrame(const VideoPacket* packet,
                         &RectangleUpdateDecoder::AllocateFrame, packet, done));
     return;
   }
-  AutoTaskRunner done_runner(done);
+  base::ScopedTaskRunner done_runner(done);
 
   TraceContext::tracer()->PrintString("AllocateFrame called.");
 
@@ -133,11 +131,11 @@ void RectangleUpdateDecoder::AllocateFrame(const VideoPacket* packet,
                              &frame_,
                              NewRunnableMethod(this,
                                  &RectangleUpdateDecoder::ProcessPacketData,
-                                 packet, done_runner.release()));
+                                 packet, done_runner.Release()));
     frame_is_new_ = true;
     return;
   }
-  ProcessPacketData(packet, done_runner.release());
+  ProcessPacketData(packet, done_runner.Release());
 }
 
 void RectangleUpdateDecoder::ProcessPacketData(
@@ -150,7 +148,7 @@ void RectangleUpdateDecoder::ProcessPacketData(
                         done));
     return;
   }
-  AutoTaskRunner done_runner(done);
+  base::ScopedTaskRunner done_runner(done);
 
   if (frame_is_new_) {
     decoder_->Reset();
diff --git a/remoting/host/client_session.cc b/remoting/host/client_session.cc
index 297ee001eb43a..1aae53c866b9b 100644
--- a/remoting/host/client_session.cc
+++ b/remoting/host/client_session.cc
@@ -5,7 +5,6 @@
 #include "remoting/host/client_session.h"
 
 #include "base/task.h"
-#include "media/base/callback.h"
 #include "remoting/host/user_authenticator.h"
 #include "remoting/proto/auth.pb.h"
 
@@ -28,7 +27,7 @@ ClientSession::~ClientSession() {
 
 void ClientSession::SuggestResolution(
     const protocol::SuggestResolutionRequest* msg, Task* done) {
-  media::AutoTaskRunner done_runner(done);
+  base::ScopedTaskRunner done_runner(done);
 
   if (!authenticated_) {
     LOG(WARNING) << "Invalid control message received "
@@ -41,7 +40,7 @@ void ClientSession::BeginSessionRequest(
     const protocol::LocalLoginCredentials* credentials, Task* done) {
   DCHECK(event_handler_);
 
-  media::AutoTaskRunner done_runner(done);
+  base::ScopedTaskRunner done_runner(done);
 
   bool success = false;
   switch (credentials->type()) {
@@ -70,19 +69,17 @@ void ClientSession::OnAuthorizationComplete(bool success) {
 
 void ClientSession::InjectKeyEvent(const protocol::KeyEvent* event,
                                    Task* done) {
-  media::AutoTaskRunner done_runner(done);
+  base::ScopedTaskRunner done_runner(done);
   if (authenticated_) {
-    done_runner.release();
-    input_stub_->InjectKeyEvent(event, done);
+    input_stub_->InjectKeyEvent(event, done_runner.Release());
   }
 }
 
 void ClientSession::InjectMouseEvent(const protocol::MouseEvent* event,
                                      Task* done) {
-  media::AutoTaskRunner done_runner(done);
+  base::ScopedTaskRunner done_runner(done);
   if (authenticated_) {
-    done_runner.release();
-    input_stub_->InjectMouseEvent(event, done);
+    input_stub_->InjectMouseEvent(event, done_runner.Release());
   }
 }
 
diff --git a/remoting/host/event_executor_linux.cc b/remoting/host/event_executor_linux.cc
index 2b632c9522e03..e01aede0c6379 100644
--- a/remoting/host/event_executor_linux.cc
+++ b/remoting/host/event_executor_linux.cc
@@ -14,7 +14,6 @@
 #include "base/logging.h"
 #include "base/message_loop.h"
 #include "base/task.h"
-#include "media/base/callback.h"
 #include "remoting/proto/internal.pb.h"
 
 namespace remoting {
@@ -278,13 +277,13 @@ bool EventExecutorLinux::Init() {
 }
 
 void EventExecutorLinux::InjectKeyEvent(const KeyEvent* event, Task* done) {
-  media::AutoTaskRunner done_runner(done);
+  base::ScopedTaskRunner done_runner(done);
 
   if (MessageLoop::current() != message_loop_) {
     message_loop_->PostTask(
         FROM_HERE,
         NewRunnableMethod(this, &EventExecutorLinux::InjectKeyEvent,
-                          event, done_runner.release()));
+                          event, done_runner.Release()));
     return;
   }
 
@@ -313,13 +312,13 @@ void EventExecutorLinux::InjectKeyEvent(const KeyEvent* event, Task* done) {
 
 void EventExecutorLinux::InjectMouseEvent(const MouseEvent* event,
                                           Task* done) {
-  media::AutoTaskRunner done_runner(done);
+  base::ScopedTaskRunner done_runner(done);
 
   if (MessageLoop::current() != message_loop_) {
     message_loop_->PostTask(
         FROM_HERE,
         NewRunnableMethod(this, &EventExecutorLinux::InjectMouseEvent,
-                          event, done_runner.release()));
+                          event, done_runner.Release()));
     return;
   }
 
diff --git a/remoting/host/event_executor_mac.cc b/remoting/host/event_executor_mac.cc
index a197bf667f94b..4c65c28d336e8 100644
--- a/remoting/host/event_executor_mac.cc
+++ b/remoting/host/event_executor_mac.cc
@@ -12,7 +12,6 @@
 #include "base/mac/scoped_cftyperef.h"
 #include "base/message_loop.h"
 #include "base/task.h"
-#include "media/base/callback.h"
 #include "remoting/host/capturer.h"
 #include "remoting/proto/internal.pb.h"
 #include "remoting/protocol/message_decoder.h"
@@ -215,7 +214,7 @@ const int kUsVkeyToKeysym[256] = {
 };
 
 void EventExecutorMac::InjectKeyEvent(const KeyEvent* event, Task* done) {
-  media::AutoTaskRunner done_runner(done);
+  base::ScopedTaskRunner done_runner(done);
 
   int key_code = event->keycode();
   if (key_code >= 0 && key_code < 256) {
@@ -251,7 +250,7 @@ void EventExecutorMac::InjectKeyEvent(const KeyEvent* event, Task* done) {
 }
 
 void EventExecutorMac::InjectMouseEvent(const MouseEvent* event, Task* done) {
-  media::AutoTaskRunner done_runner(done);
+  base::ScopedTaskRunner done_runner(done);
 
   if (event->has_x() && event->has_y()) {
     // TODO(wez): Checking the validity of the MouseEvent should be done in core
diff --git a/remoting/host/event_executor_win.cc b/remoting/host/event_executor_win.cc
index 6eb2c9b7850c2..2f7e737fb715b 100644
--- a/remoting/host/event_executor_win.cc
+++ b/remoting/host/event_executor_win.cc
@@ -46,13 +46,13 @@ EventExecutorWin::EventExecutorWin(MessageLoop* message_loop,
 }
 
 void EventExecutorWin::InjectKeyEvent(const KeyEvent* event, Task* done) {
-  media::AutoTaskRunner done_runner(done);
+  base::ScopedTaskRunner done_runner(done);
 
   if (MessageLoop::current() != message_loop_) {
     message_loop_->PostTask(
         FROM_HERE,
         NewRunnableMethod(this, &EventExecutorWin::InjectKeyEvent,
-                          event, done_runner.release()));
+                          event, done_runner.Release()));
     return;
   }
 
@@ -60,13 +60,13 @@ void EventExecutorWin::InjectKeyEvent(const KeyEvent* event, Task* done) {
 }
 
 void EventExecutorWin::InjectMouseEvent(const MouseEvent* event, Task* done) {
-  media::AutoTaskRunner done_runner(done);
+  base::ScopedTaskRunner done_runner(done);
 
   if (MessageLoop::current() != message_loop_) {
     message_loop_->PostTask(
         FROM_HERE,
         NewRunnableMethod(this, &EventExecutorWin::InjectMouseEvent,
-                          event, done_runner.release()));
+                          event, done_runner.Release()));
     return;
   }
 
diff --git a/remoting/host/screen_recorder.cc b/remoting/host/screen_recorder.cc
index 38b993245658c..7533b5ffa3de7 100644
--- a/remoting/host/screen_recorder.cc
+++ b/remoting/host/screen_recorder.cc
@@ -11,7 +11,6 @@
 #include "base/stl_util-inl.h"
 #include "base/task.h"
 #include "base/time.h"
-#include "media/base/callback.h"
 #include "remoting/base/capture_data.h"
 #include "remoting/base/tracer.h"
 #include "remoting/proto/control.pb.h"
@@ -151,7 +150,7 @@ void ScreenRecorder::DoStart() {
 void ScreenRecorder::DoStop(Task* done_task) {
   DCHECK_EQ(capture_loop_, MessageLoop::current());
 
-  media::AutoTaskRunner done_runner(done_task);
+  base::ScopedTaskRunner done_runner(done_task);
 
   // We might have not started when we receive a stop command, simply run the
   // task and then return.
@@ -167,7 +166,7 @@ void ScreenRecorder::DoStop(Task* done_task) {
         FROM_HERE,
         NewTracedMethod(this,
                         &ScreenRecorder::DoStopOnNetworkThread,
-                        done_runner.release()));
+                        done_runner.Release()));
     return;
   }
 }
diff --git a/tools/clang/plugins/ChromeClassTester.cpp b/tools/clang/plugins/ChromeClassTester.cpp
index 9911fd930f498..101877bfff60c 100644
--- a/tools/clang/plugins/ChromeClassTester.cpp
+++ b/tools/clang/plugins/ChromeClassTester.cpp
@@ -114,7 +114,6 @@ void ChromeClassTester::BuildBannedLists() {
   ignored_record_names_.insert("Validators");
 
   // RAII class that's simple enough (media/base/callback.h).
-  ignored_record_names_.insert("AutoTaskRunner");
   ignored_record_names_.insert("AutoCallbackRunner");
 
   // Has a UNIT_TEST only constructor. Isn't *terribly* complex...