Extend VideoCaptureDevice::Client::OnError() to have a tracked_objects::Location param.

Every now and then a bug report would include WebRtc
logs with an error string: this is generated in
VideoCaptureDevice::Client::OnError() and has no
origin information. This CL adds that in a way that
clients add the classical FROM_HERE, so that the error
log includes the originating file and line.

Review URL: https://codereview.chromium.org/1418263006

Cr-Commit-Position: refs/heads/master@{#357154}
diff --git a/content/browser/media/capture/aura_window_capture_machine.cc b/content/browser/media/capture/aura_window_capture_machine.cc
index e5019f7..11150ea 100644
--- a/content/browser/media/capture/aura_window_capture_machine.cc
+++ b/content/browser/media/capture/aura_window_capture_machine.cc
@@ -485,7 +485,7 @@
 
   InternalStop(base::Bind(&base::DoNothing));
 
-  oracle_proxy_->ReportError("OnWindowDestroying()");
+  oracle_proxy_->ReportError(FROM_HERE, "OnWindowDestroying()");
 }
 
 void AuraWindowCaptureMachine::OnWindowAddedToRootWindow(
diff --git a/content/browser/media/capture/desktop_capture_device.cc b/content/browser/media/capture/desktop_capture_device.cc
index 6cc4839..bc16454 100644
--- a/content/browser/media/capture/desktop_capture_device.cc
+++ b/content/browser/media/capture/desktop_capture_device.cc
@@ -206,9 +206,7 @@
   capture_in_progress_ = false;
 
   if (!frame) {
-    std::string log("Failed to capture a frame.");
-    LOG(ERROR) << log;
-    client_->OnError(log);
+    client_->OnError(FROM_HERE, "Failed to capture a frame.");
     return;
   }
 
diff --git a/content/browser/media/capture/desktop_capture_device_aura_unittest.cc b/content/browser/media/capture/desktop_capture_device_aura_unittest.cc
index 790334e..dd12640c 100644
--- a/content/browser/media/capture/desktop_capture_device_aura_unittest.cc
+++ b/content/browser/media/capture/desktop_capture_device_aura_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "content/browser/media/capture/desktop_capture_device_aura.h"
 
+#include "base/location.h"
 #include "base/synchronization/waitable_event.h"
 #include "content/browser/browser_thread_impl.h"
 #include "content/public/browser/desktop_media_id.h"
@@ -54,7 +55,9 @@
   MOCK_METHOD0(DoReserveOutputBuffer, void(void));
   MOCK_METHOD0(DoOnIncomingCapturedBuffer, void(void));
   MOCK_METHOD0(DoOnIncomingCapturedVideoFrame, void(void));
-  MOCK_METHOD1(OnError, void(const std::string& reason));
+  MOCK_METHOD2(OnError,
+               void(const tracked_objects::Location& from_here,
+                    const std::string& reason));
 
   // Trampoline methods to workaround GMOCK problems with scoped_ptr<>.
   scoped_ptr<Buffer> ReserveOutputBuffer(
@@ -142,7 +145,7 @@
   ASSERT_TRUE(capture_device.get());
 
   scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
-  EXPECT_CALL(*client, OnError(_)).Times(0);
+  EXPECT_CALL(*client, OnError(_, _)).Times(0);
 
   media::VideoCaptureParams capture_params;
   capture_params.requested_format.frame_size.SetSize(640, 480);
diff --git a/content/browser/media/capture/desktop_capture_device_unittest.cc b/content/browser/media/capture/desktop_capture_device_unittest.cc
index afaac44..a754ff7 100644
--- a/content/browser/media/capture/desktop_capture_device_unittest.cc
+++ b/content/browser/media/capture/desktop_capture_device_unittest.cc
@@ -75,7 +75,9 @@
   MOCK_METHOD0(DoReserveOutputBuffer, void(void));
   MOCK_METHOD0(DoOnIncomingCapturedBuffer, void(void));
   MOCK_METHOD0(DoOnIncomingCapturedVideoFrame, void(void));
-  MOCK_METHOD1(OnError, void(const std::string& reason));
+  MOCK_METHOD2(OnError,
+               void(const tracked_objects::Location& from_here,
+                    const std::string& reason));
 
   // Trampoline methods to workaround GMOCK problems with scoped_ptr<>.
   scoped_ptr<Buffer> ReserveOutputBuffer(
@@ -283,7 +285,7 @@
   int frame_size;
 
   scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
-  EXPECT_CALL(*client, OnError(_)).Times(0);
+  EXPECT_CALL(*client, OnError(_, _)).Times(0);
   EXPECT_CALL(*client, OnIncomingCapturedData(_, _, _, _, _)).WillRepeatedly(
       DoAll(SaveArg<1>(&frame_size),
             SaveArg<2>(&format),
@@ -317,7 +319,7 @@
   base::WaitableEvent done_event(false, false);
 
   scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
-  EXPECT_CALL(*client, OnError(_)).Times(0);
+  EXPECT_CALL(*client, OnError(_, _)).Times(0);
   EXPECT_CALL(*client, OnIncomingCapturedData(_, _, _, _, _)).WillRepeatedly(
       DoAll(WithArg<2>(Invoke(&format_checker,
                               &FormatChecker::ExpectAcceptableSize)),
@@ -357,7 +359,7 @@
   base::WaitableEvent done_event(false, false);
 
   scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
-  EXPECT_CALL(*client, OnError(_)).Times(0);
+  EXPECT_CALL(*client, OnError(_,_)).Times(0);
   EXPECT_CALL(*client, OnIncomingCapturedData(_, _, _, _, _)).WillRepeatedly(
       DoAll(WithArg<2>(Invoke(&format_checker,
                               &FormatChecker::ExpectAcceptableSize)),
@@ -402,7 +404,7 @@
   base::WaitableEvent done_event(false, false);
 
   scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
-  EXPECT_CALL(*client, OnError(_)).Times(0);
+  EXPECT_CALL(*client, OnError(_,_)).Times(0);
   EXPECT_CALL(*client, OnIncomingCapturedData(_, _, _, _, _)).WillRepeatedly(
       DoAll(WithArg<2>(Invoke(&format_checker,
                               &FormatChecker::ExpectAcceptableSize)),
@@ -449,7 +451,7 @@
       webrtc::DesktopSize(kTestFrameWidth1, kTestFrameHeight1)));
 
   scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
-  EXPECT_CALL(*client, OnError(_)).Times(0);
+  EXPECT_CALL(*client, OnError(_,_)).Times(0);
   EXPECT_CALL(*client, OnIncomingCapturedData(_, _, _, _, _)).WillRepeatedly(
       DoAll(Invoke(this, &DesktopCaptureDeviceTest::CopyFrame),
             SaveArg<1>(&frame_size),
@@ -492,7 +494,7 @@
       webrtc::DesktopSize(kTestFrameWidth1, kTestFrameHeight1)));
 
   scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
-  EXPECT_CALL(*client, OnError(_)).Times(0);
+  EXPECT_CALL(*client, OnError(_,_)).Times(0);
   EXPECT_CALL(*client, OnIncomingCapturedData(_, _, _, _, _)).WillRepeatedly(
       DoAll(Invoke(this, &DesktopCaptureDeviceTest::CopyFrame),
             SaveArg<1>(&frame_size),
diff --git a/content/browser/media/capture/web_contents_video_capture_device.cc b/content/browser/media/capture/web_contents_video_capture_device.cc
index 64312d9a..e8e55ad 100644
--- a/content/browser/media/capture/web_contents_video_capture_device.cc
+++ b/content/browser/media/capture/web_contents_video_capture_device.cc
@@ -762,7 +762,8 @@
     if (IsStarted()) {
       // Tracking of WebContents and/or its main frame has failed before Stop()
       // was called, so report this as an error:
-      oracle_proxy_->ReportError("WebContents and/or main frame are gone.");
+      oracle_proxy_->ReportError(FROM_HERE,
+                                 "WebContents and/or main frame are gone.");
     }
     return;
   }
diff --git a/content/browser/media/capture/web_contents_video_capture_device_unittest.cc b/content/browser/media/capture/web_contents_video_capture_device_unittest.cc
index c8ea3db7..7a6463a4 100644
--- a/content/browser/media/capture/web_contents_video_capture_device_unittest.cc
+++ b/content/browser/media/capture/web_contents_video_capture_device_unittest.cc
@@ -407,7 +407,10 @@
         frame->visible_rect().size());
   }
 
-  void OnError(const std::string& reason) override { error_callback_.Run(); }
+  void OnError(const tracked_objects::Location& from_here,
+               const std::string& reason) override {
+    error_callback_.Run();
+  }
 
   double GetBufferPoolUtilization() const override { return 0.0; }
 
diff --git a/content/browser/renderer_host/media/video_capture_controller_unittest.cc b/content/browser/renderer_host/media/video_capture_controller_unittest.cc
index dc82a26..a030323 100644
--- a/content/browser/renderer_host/media/video_capture_controller_unittest.cc
+++ b/content/browser/renderer_host/media/video_capture_controller_unittest.cc
@@ -594,7 +594,7 @@
   // Start with one client.
   controller_->AddClient(
       route_id, client_a_.get(), base::kNullProcessHandle, 100, session_100);
-  device_->OnError("Test Error");
+  device_->OnError(FROM_HERE,  "Test Error");
   EXPECT_CALL(*client_a_, DoError(route_id)).Times(1);
   base::RunLoop().RunUntilIdle();
   Mock::VerifyAndClearExpectations(client_a_.get());
@@ -651,7 +651,7 @@
 
   scoped_refptr<media::VideoFrame> video_frame =
       WrapI420Buffer(dims, static_cast<uint8*>(buffer->data()));
-  device_->OnError("Test Error");
+  device_->OnError(FROM_HERE, "Test Error");
   device_->OnIncomingCapturedVideoFrame(buffer.Pass(), video_frame,
                                         base::TimeTicks());
 
diff --git a/content/browser/renderer_host/media/video_capture_device_client.cc b/content/browser/renderer_host/media/video_capture_device_client.cc
index 7ba7761..0cd2d4f91 100644
--- a/content/browser/renderer_host/media/video_capture_device_client.cc
+++ b/content/browser/renderer_host/media/video_capture_device_client.cc
@@ -8,6 +8,7 @@
 
 #include "base/bind.h"
 #include "base/command_line.h"
+#include "base/location.h"
 #include "base/strings/stringprintf.h"
 #include "base/trace_event/trace_event.h"
 #include "content/browser/compositor/image_transport_factory.h"
@@ -393,12 +394,13 @@
 }
 
 void VideoCaptureDeviceClient::OnError(
+    const tracked_objects::Location& from_here,
     const std::string& reason) {
   const std::string log_message = base::StringPrintf(
-      "Error on video capture: %s, OS message: %s",
-      reason.c_str(),
-      logging::SystemErrorCodeToString(
-          logging::GetLastSystemErrorCode()).c_str());
+      "Error on %s:%d: %s, OS message: %s", from_here.file_name(),
+      from_here.line_number(), reason.c_str(),
+      logging::SystemErrorCodeToString(logging::GetLastSystemErrorCode())
+          .c_str());
   DLOG(ERROR) << log_message;
   OnLog(log_message);
   BrowserThread::PostTask(BrowserThread::IO,
diff --git a/content/browser/renderer_host/media/video_capture_device_client.h b/content/browser/renderer_host/media/video_capture_device_client.h
index 844c611a..111839c 100644
--- a/content/browser/renderer_host/media/video_capture_device_client.h
+++ b/content/browser/renderer_host/media/video_capture_device_client.h
@@ -65,7 +65,8 @@
       scoped_ptr<Buffer> buffer,
       const scoped_refptr<media::VideoFrame>& frame,
       const base::TimeTicks& timestamp) override;
-  void OnError(const std::string& reason) override;
+  void OnError(const tracked_objects::Location& from_here,
+               const std::string& reason) override;
   void OnLog(const std::string& message) override;
   double GetBufferPoolUtilization() const override;
 
diff --git a/content/browser/renderer_host/media/video_capture_manager.cc b/content/browser/renderer_host/media/video_capture_manager.cc
index 003c2897..43788fb 100644
--- a/content/browser/renderer_host/media/video_capture_manager.cc
+++ b/content/browser/renderer_host/media/video_capture_manager.cc
@@ -431,7 +431,7 @@
   }
 
   if (!video_capture_device) {
-    device_client->OnError("Could not create capture device");
+    device_client->OnError(FROM_HERE, "Could not create capture device");
     return nullptr;
   }
 
diff --git a/media/capture/content/screen_capture_device_core.cc b/media/capture/content/screen_capture_device_core.cc
index d99ca5a..d089eae5 100644
--- a/media/capture/content/screen_capture_device_core.cc
+++ b/media/capture/content/screen_capture_device_core.cc
@@ -46,11 +46,11 @@
         params.requested_format.pixel_storage == PIXEL_STORAGE_CPU) &&
       !(params.requested_format.pixel_format == PIXEL_FORMAT_ARGB &&
         params.requested_format.pixel_storage == PIXEL_STORAGE_TEXTURE)) {
-    const std::string error_msg = base::StringPrintf(
-        "unsupported format: %s",
-        VideoCaptureFormat::ToString(params.requested_format).c_str());
-    DVLOG(1) << error_msg;
-    client->OnError(error_msg);
+    client->OnError(
+        FROM_HERE,
+        base::StringPrintf(
+            "unsupported format: %s",
+            VideoCaptureFormat::ToString(params.requested_format).c_str()));
     return;
   }
 
@@ -80,11 +80,8 @@
 
 void ScreenCaptureDeviceCore::CaptureStarted(bool success) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  if (!success) {
-    std::string reason("Failed to start capture machine.");
-    DVLOG(1) << reason;
-    Error(reason);
-  }
+  if (!success)
+    Error(FROM_HERE, "Failed to start capture machine.");
 }
 
 ScreenCaptureDeviceCore::ScreenCaptureDeviceCore(
@@ -107,8 +104,9 @@
   DCHECK(thread_checker_.CalledOnValidThread());
 
 #ifndef NDEBUG
-  static const char* kStateNames[] = {
-      "Idle", "Allocated", "Capturing", "Error"};
+  static const char* kStateNames[] = {"Idle", "Capturing", "Error"};
+  static_assert(arraysize(kStateNames) == kLastCaptureState,
+                "Different number of states and textual descriptions");
   DVLOG(1) << "State change: " << kStateNames[state_] << " --> "
            << kStateNames[next_state];
 #endif
@@ -116,14 +114,15 @@
   state_ = next_state;
 }
 
-void ScreenCaptureDeviceCore::Error(const std::string& reason) {
+void ScreenCaptureDeviceCore::Error(const tracked_objects::Location& from_here,
+                                    const std::string& reason) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
   if (state_ == kIdle)
     return;
 
   if (oracle_proxy_.get())
-    oracle_proxy_->ReportError(reason);
+    oracle_proxy_->ReportError(from_here, reason);
 
   StopAndDeAllocate();
   TransitionStateTo(kError);
diff --git a/media/capture/content/screen_capture_device_core.h b/media/capture/content/screen_capture_device_core.h
index 0720094..d7250e74 100644
--- a/media/capture/content/screen_capture_device_core.h
+++ b/media/capture/content/screen_capture_device_core.h
@@ -14,6 +14,10 @@
 #include "media/capture/content/thread_safe_capture_oracle.h"
 #include "media/capture/video/video_capture_device.h"
 
+namespace tracked_objects {
+class Location;
+}  // namespace tracked_objects
+
 namespace media {
 
 struct VideoCaptureParams;
@@ -68,7 +72,7 @@
 
  private:
   // Flag indicating current state.
-  enum State { kIdle, kCapturing, kError };
+  enum State { kIdle, kCapturing, kError, kLastCaptureState };
 
   void TransitionStateTo(State next_state);
 
@@ -77,7 +81,8 @@
   void CaptureStarted(bool success);
 
   // Stops capturing and notifies client_ of an error state.
-  void Error(const std::string& reason);
+  void Error(const tracked_objects::Location& from_here,
+             const std::string& reason);
 
   // Tracks that all activity occurs on the media stream manager's thread.
   base::ThreadChecker thread_checker_;
diff --git a/media/capture/content/thread_safe_capture_oracle.cc b/media/capture/content/thread_safe_capture_oracle.cc
index 22b1dcfc..bda73de 100644
--- a/media/capture/content/thread_safe_capture_oracle.cc
+++ b/media/capture/content/thread_safe_capture_oracle.cc
@@ -145,10 +145,12 @@
   client_.reset();
 }
 
-void ThreadSafeCaptureOracle::ReportError(const std::string& reason) {
+void ThreadSafeCaptureOracle::ReportError(
+    const tracked_objects::Location& from_here,
+    const std::string& reason) {
   base::AutoLock guard(lock_);
   if (client_)
-    client_->OnError(reason);
+    client_->OnError(from_here, reason);
 }
 
 void ThreadSafeCaptureOracle::DidCaptureFrame(
diff --git a/media/capture/content/thread_safe_capture_oracle.h b/media/capture/content/thread_safe_capture_oracle.h
index 1aa905e..a410000 100644
--- a/media/capture/content/thread_safe_capture_oracle.h
+++ b/media/capture/content/thread_safe_capture_oracle.h
@@ -14,6 +14,10 @@
 #include "media/capture/content/video_capture_oracle.h"
 #include "media/capture/video/video_capture_device.h"
 
+namespace tracked_objects {
+class Location;
+}  // namespace tracked_objects
+
 namespace media {
 
 struct VideoCaptureParams;
@@ -63,7 +67,8 @@
   void Stop();
 
   // Signal an error to the client.
-  void ReportError(const std::string& reason);
+  void ReportError(const tracked_objects::Location& from_here,
+                   const std::string& reason);
 
  private:
   friend class base::RefCountedThreadSafe<ThreadSafeCaptureOracle>;
diff --git a/media/capture/video/android/video_capture_device_android.cc b/media/capture/video/android/video_capture_device_android.cc
index 69d8b05..ae38e99 100644
--- a/media/capture/video/android/video_capture_device_android.cc
+++ b/media/capture/video/android/video_capture_device_android.cc
@@ -68,7 +68,7 @@
       params.requested_format.frame_size.height(),
       params.requested_format.frame_rate);
   if (!ret) {
-    SetErrorState("failed to allocate");
+    SetErrorState(FROM_HERE, "failed to allocate");
     return;
   }
 
@@ -96,7 +96,7 @@
 
   ret = Java_VideoCapture_startCapture(env, j_capture_.obj());
   if (!ret) {
-    SetErrorState("failed to start capture");
+    SetErrorState(FROM_HERE, "failed to start capture");
     return;
   }
 
@@ -118,7 +118,7 @@
 
   jboolean ret = Java_VideoCapture_stopCapture(env, j_capture_.obj());
   if (!ret) {
-    SetErrorState("failed to stop capture");
+    SetErrorState(FROM_HERE, "failed to stop capture");
     return;
   }
 
@@ -171,7 +171,8 @@
 void VideoCaptureDeviceAndroid::OnError(JNIEnv* env,
                                         jobject obj,
                                         jstring message) {
-  SetErrorState(base::android::ConvertJavaStringToUTF8(env, message));
+  SetErrorState(FROM_HERE,
+                base::android::ConvertJavaStringToUTF8(env, message));
 }
 
 VideoPixelFormat VideoCaptureDeviceAndroid::GetColorspace() {
@@ -191,12 +192,14 @@
   }
 }
 
-void VideoCaptureDeviceAndroid::SetErrorState(const std::string& reason) {
+void VideoCaptureDeviceAndroid::SetErrorState(
+    const tracked_objects::Location& from_here,
+    const std::string& reason) {
   {
     base::AutoLock lock(lock_);
     state_ = kError;
   }
-  client_->OnError(reason);
+  client_->OnError(from_here, reason);
 }
 
 }  // namespace media
diff --git a/media/capture/video/android/video_capture_device_android.h b/media/capture/video/android/video_capture_device_android.h
index ccab5e2..3416ef2 100644
--- a/media/capture/video/android/video_capture_device_android.h
+++ b/media/capture/video/android/video_capture_device_android.h
@@ -15,6 +15,10 @@
 #include "media/base/media_export.h"
 #include "media/capture/video/video_capture_device.h"
 
+namespace tracked_objects {
+class Location;
+}  // namespace tracked_
+
 namespace media {
 
 // VideoCaptureDevice on Android. The VideoCaptureDevice API's are called
@@ -70,7 +74,8 @@
   };
 
   VideoPixelFormat GetColorspace();
-  void SetErrorState(const std::string& reason);
+  void SetErrorState(const tracked_objects::Location& from_here,
+                     const std::string& reason);
 
   // Prevent racing on accessing |state_| and |client_| since both could be
   // accessed from different threads.
diff --git a/media/capture/video/fake_video_capture_device_unittest.cc b/media/capture/video/fake_video_capture_device_unittest.cc
index 53edf182..fa1a95d 100644
--- a/media/capture/video/fake_video_capture_device_unittest.cc
+++ b/media/capture/video/fake_video_capture_device_unittest.cc
@@ -54,7 +54,9 @@
 
 class MockClient : public VideoCaptureDevice::Client {
  public:
-  MOCK_METHOD1(OnError, void(const std::string& reason));
+  MOCK_METHOD2(OnError,
+               void(const tracked_objects::Location& from_here,
+                    const std::string& reason));
 
   explicit MockClient(base::Callback<void(const VideoCaptureFormat&)> frame_cb)
       : frame_cb_(frame_cb) {}
@@ -141,7 +143,7 @@
     device_enumeration_listener_ = new DeviceEnumerationListener();
   }
 
-  void SetUp() override { EXPECT_CALL(*client_, OnError(_)).Times(0); }
+  void SetUp() override { EXPECT_CALL(*client_, OnError(_, _)).Times(0); }
 
   void OnFrameCaptured(const VideoCaptureFormat& format) {
     last_format_ = format;
diff --git a/media/capture/video/file_video_capture_device.cc b/media/capture/video/file_video_capture_device.cc
index 073c0a1..d241cc39 100644
--- a/media/capture/video/file_video_capture_device.cc
+++ b/media/capture/video/file_video_capture_device.cc
@@ -333,7 +333,7 @@
   DCHECK(!file_parser_);
   file_parser_ = GetVideoFileParser(file_path_, &capture_format_);
   if (!file_parser_) {
-    client_->OnError("Could not open Video file");
+    client_->OnError(FROM_HERE, "Could not open Video file");
     return;
   }
 
diff --git a/media/capture/video/linux/v4l2_capture_delegate.cc b/media/capture/video/linux/v4l2_capture_delegate.cc
index 88f5075..4bb2b8a 100644
--- a/media/capture/video/linux/v4l2_capture_delegate.cc
+++ b/media/capture/video/linux/v4l2_capture_delegate.cc
@@ -180,7 +180,7 @@
   // Need to open camera with O_RDWR after Linux kernel 3.3.
   device_fd_.reset(HANDLE_EINTR(open(device_name_.id().c_str(), O_RDWR)));
   if (!device_fd_.is_valid()) {
-    SetErrorState("Failed to open V4L2 device driver file.");
+    SetErrorState(FROM_HERE, "Failed to open V4L2 device driver file.");
     return;
   }
 
@@ -191,7 +191,7 @@
          !(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT) &&
          !(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT_MPLANE)))) {
     device_fd_.reset();
-    SetErrorState("This is not a V4L2 video capture device");
+    SetErrorState(FROM_HERE, "This is not a V4L2 video capture device");
     return;
   }
 
@@ -208,7 +208,7 @@
     best = std::find(desired_v4l2_formats.begin(), best, fmtdesc.pixelformat);
   }
   if (best == desired_v4l2_formats.end()) {
-    SetErrorState("Failed to find a supported camera format.");
+    SetErrorState(FROM_HERE, "Failed to find a supported camera format.");
     return;
   }
 
@@ -216,18 +216,18 @@
 
   video_fmt_.type = capture_type_;
   if (!FillV4L2Format(&video_fmt_, width, height, *best)) {
-    SetErrorState("Failed filling in V4L2 Format");
+    SetErrorState(FROM_HERE, "Failed filling in V4L2 Format");
     return;
   }
 
   if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_S_FMT, &video_fmt_)) < 0) {
-    SetErrorState("Failed to set video capture format");
+    SetErrorState(FROM_HERE, "Failed to set video capture format");
     return;
   }
   const VideoPixelFormat pixel_format =
       V4l2FourCcToChromiumPixelFormat(video_fmt_.fmt.pix.pixelformat);
   if (pixel_format == PIXEL_FORMAT_UNKNOWN) {
-    SetErrorState("Unsupported pixel format");
+    SetErrorState(FROM_HERE, "Unsupported pixel format");
     return;
   }
 
@@ -247,7 +247,7 @@
 
       if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_S_PARM, &streamparm)) <
           0) {
-        SetErrorState("Failed to set camera framerate");
+        SetErrorState(FROM_HERE, "Failed to set camera framerate");
         return;
       }
       DVLOG(2) << "Actual camera driverframerate: "
@@ -282,19 +282,19 @@
   r_buffer.memory = V4L2_MEMORY_MMAP;
   r_buffer.count = kNumVideoBuffers;
   if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_REQBUFS, &r_buffer)) < 0) {
-    SetErrorState("Error requesting MMAP buffers from V4L2");
+    SetErrorState(FROM_HERE, "Error requesting MMAP buffers from V4L2");
     return;
   }
   for (unsigned int i = 0; i < r_buffer.count; ++i) {
     if (!MapAndQueueBuffer(i)) {
-      SetErrorState("Allocate buffer failed");
+      SetErrorState(FROM_HERE, "Allocate buffer failed");
       return;
     }
   }
 
   if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_STREAMON, &capture_type_)) <
       0) {
-    SetErrorState("VIDIOC_STREAMON failed");
+    SetErrorState(FROM_HERE, "VIDIOC_STREAMON failed");
     return;
   }
 
@@ -310,7 +310,7 @@
   // thus munmap()ing the v4l2_buffers, and then return them to the OS.
   if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_STREAMOFF, &capture_type_)) <
       0) {
-    SetErrorState("VIDIOC_STREAMOFF failed");
+    SetErrorState(FROM_HERE, "VIDIOC_STREAMOFF failed");
     return;
   }
 
@@ -321,7 +321,7 @@
   r_buffer.memory = V4L2_MEMORY_MMAP;
   r_buffer.count = 0;
   if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_REQBUFS, &r_buffer)) < 0)
-    SetErrorState("Failed to VIDIOC_REQBUFS with count = 0");
+    SetErrorState(FROM_HERE, "Failed to VIDIOC_REQBUFS with count = 0");
 
   // At this point we can close the device.
   // This is also needed for correctly changing settings later via VIDIOC_S_FMT.
@@ -377,7 +377,7 @@
   device_pfd.events = POLLIN;
   const int result = HANDLE_EINTR(poll(&device_pfd, 1, kCaptureTimeoutMs));
   if (result < 0) {
-    SetErrorState("Poll failed");
+    SetErrorState(FROM_HERE, "Poll failed");
     return;
   }
   // Check if poll() timed out; track the amount of times it did in a row and
@@ -385,7 +385,8 @@
   if (result == 0) {
     timeout_count_++;
     if (timeout_count_ >= kContinuousTimeoutLimit) {
-      SetErrorState("Multiple continuous timeouts while read-polling.");
+      SetErrorState(FROM_HERE,
+                    "Multiple continuous timeouts while read-polling.");
       timeout_count_ = 0;
       return;
     }
@@ -399,7 +400,7 @@
     FillV4L2Buffer(&buffer, 0);
 
     if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_DQBUF, &buffer)) < 0) {
-      SetErrorState("Failed to dequeue capture buffer");
+      SetErrorState(FROM_HERE, "Failed to dequeue capture buffer");
       return;
     }
 
@@ -407,7 +408,7 @@
     SendBuffer(buffer_tracker_pool_[buffer.index], video_fmt_);
 
     if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_QBUF, &buffer)) < 0) {
-      SetErrorState("Failed to enqueue capture buffer");
+      SetErrorState(FROM_HERE, "Failed to enqueue capture buffer");
       return;
     }
   }
@@ -416,10 +417,12 @@
       FROM_HERE, base::Bind(&V4L2CaptureDelegate::DoCapture, this));
 }
 
-void V4L2CaptureDelegate::SetErrorState(const std::string& reason) {
+void V4L2CaptureDelegate::SetErrorState(
+    const tracked_objects::Location& from_here,
+    const std::string& reason) {
   DCHECK(v4l2_task_runner_->BelongsToCurrentThread());
   is_capturing_ = false;
-  client_->OnError(reason);
+  client_->OnError(from_here, reason);
 }
 
 }  // namespace media
diff --git a/media/capture/video/linux/v4l2_capture_delegate.h b/media/capture/video/linux/v4l2_capture_delegate.h
index 1bb1735..28cec82 100644
--- a/media/capture/video/linux/v4l2_capture_delegate.h
+++ b/media/capture/video/linux/v4l2_capture_delegate.h
@@ -15,6 +15,10 @@
 #include "base/memory/ref_counted.h"
 #include "media/capture/video/video_capture_device.h"
 
+namespace tracked_objects {
+class Location;
+}  // namespace tracked_objects
+
 namespace media {
 
 // Class doing the actual Linux capture using V4L2 API. V4L2 SPLANE/MPLANE
@@ -137,7 +141,8 @@
   // for filling in the planar-dependent parts.
   void FillV4L2Buffer(v4l2_buffer* buffer, int i) const;
   void DoCapture();
-  void SetErrorState(const std::string& reason);
+  void SetErrorState(const tracked_objects::Location& from_here,
+                     const std::string& reason);
 
   const v4l2_buf_type capture_type_;
   const scoped_refptr<base::SingleThreadTaskRunner> v4l2_task_runner_;
diff --git a/media/capture/video/linux/video_capture_device_linux.cc b/media/capture/video/linux/video_capture_device_linux.cc
index cbf2b490..0d55d27 100644
--- a/media/capture/video/linux/video_capture_device_linux.cc
+++ b/media/capture/video/linux/video_capture_device_linux.cc
@@ -101,7 +101,7 @@
   capture_impl_ = V4L2CaptureDelegate::CreateV4L2CaptureDelegate(
       device_name_, v4l2_thread_.task_runner(), line_frequency);
   if (!capture_impl_) {
-    client->OnError("Failed to create VideoCaptureDelegate");
+    client->OnError(FROM_HERE, "Failed to create VideoCaptureDelegate");
     return;
   }
   v4l2_thread_.message_loop()->PostTask(
diff --git a/media/capture/video/mac/video_capture_device_avfoundation_mac.mm b/media/capture/video/mac/video_capture_device_avfoundation_mac.mm
index deb1408..5f1893ae 100644
--- a/media/capture/video/mac/video_capture_device_avfoundation_mac.mm
+++ b/media/capture/video/mac/video_capture_device_avfoundation_mac.mm
@@ -6,6 +6,7 @@
 
 #import <CoreVideo/CoreVideo.h>
 
+#include "base/location.h"
 #include "base/logging.h"
 #include "base/mac/foundation_util.h"
 #include "media/base/video_capture_types.h"
@@ -351,7 +352,7 @@
   DLOG(ERROR) << [error UTF8String];
   base::AutoLock lock(lock_);
   if (frameReceiver_)
-    frameReceiver_->ReceiveError([error UTF8String]);
+    frameReceiver_->ReceiveError(FROM_HERE, [error UTF8String]);
 }
 
 @end
diff --git a/media/capture/video/mac/video_capture_device_decklink_mac.h b/media/capture/video/mac/video_capture_device_decklink_mac.h
index e03765ab..8718e03 100644
--- a/media/capture/video/mac/video_capture_device_decklink_mac.h
+++ b/media/capture/video/mac/video_capture_device_decklink_mac.h
@@ -19,6 +19,10 @@
 class DeckLinkCaptureDelegate;
 }  // namespace
 
+namespace tracked_objects {
+class Location;
+}  // namespace tracked_objects
+
 namespace media {
 
 // Extension of VideoCaptureDevice to create and manipulate Blackmagic devices.
@@ -52,7 +56,8 @@
                               base::TimeTicks timestamp);
 
   // Forwarder to VideoCaptureDevice::Client::OnError().
-  void SendErrorString(const std::string& reason);
+  void SendErrorString(const tracked_objects::Location& from_here,
+                       const std::string& reason);
 
   // Forwarder to VideoCaptureDevice::Client::OnLog().
   void SendLogString(const std::string& message);
diff --git a/media/capture/video/mac/video_capture_device_decklink_mac.mm b/media/capture/video/mac/video_capture_device_decklink_mac.mm
index c73cb40..6877f96 100644
--- a/media/capture/video/mac/video_capture_device_decklink_mac.mm
+++ b/media/capture/video/mac/video_capture_device_decklink_mac.mm
@@ -69,7 +69,8 @@
   ULONG Release() override;
 
   // Forwarder to VideoCaptureDeviceDeckLinkMac::SendErrorString().
-  void SendErrorString(const std::string& reason);
+  void SendErrorString(const tracked_objects::Location& from_here,
+                       const std::string& reason);
 
   // Forwarder to VideoCaptureDeviceDeckLinkMac::SendLogString().
   void SendLogString(const std::string& message);
@@ -143,21 +144,21 @@
     }
   }
   if (!decklink_local.get()) {
-    SendErrorString("Device id not found in the system");
+    SendErrorString(FROM_HERE, "Device id not found in the system");
     return;
   }
 
   ScopedDeckLinkPtr<IDeckLinkInput> decklink_input_local;
   if (decklink_local->QueryInterface(
           IID_IDeckLinkInput, decklink_input_local.ReceiveVoid()) != S_OK) {
-    SendErrorString("Error querying input interface.");
+    SendErrorString(FROM_HERE, "Error querying input interface.");
     return;
   }
 
   ScopedDeckLinkPtr<IDeckLinkDisplayModeIterator> display_mode_iter;
   if (decklink_input_local->GetDisplayModeIterator(
           display_mode_iter.Receive()) != S_OK) {
-    SendErrorString("Error creating Display Mode Iterator");
+    SendErrorString(FROM_HERE, "Error creating Display Mode Iterator");
     return;
   }
 
@@ -178,7 +179,7 @@
     display_mode.Release();
   }
   if (!chosen_display_mode.get()) {
-    SendErrorString("Could not find a display mode");
+    SendErrorString(FROM_HERE, "Could not find a display mode");
     return;
   }
 #if !defined(NDEBUG)
@@ -194,13 +195,13 @@
   if (decklink_input_local->EnableVideoInput(
           chosen_display_mode->GetDisplayMode(), bmdFormat8BitYUV,
           bmdVideoInputFlagDefault) != S_OK) {
-    SendErrorString("Could not select the video format we like.");
+    SendErrorString(FROM_HERE, "Could not select the video format we like.");
     return;
   }
 
   decklink_input_local->SetCallback(this);
   if (decklink_input_local->StartStreams() != S_OK)
-    SendErrorString("Could not start capturing");
+    SendErrorString(FROM_HERE, "Could not start capturing");
 
   decklink_.swap(decklink_local);
   decklink_input_.swap(decklink_input_local);
@@ -244,7 +245,7 @@
       pixel_format = media::PIXEL_FORMAT_ARGB;
       break;
     default:
-      SendErrorString("Unsupported pixel format");
+      SendErrorString(FROM_HERE, "Unsupported pixel format");
       break;
   }
 
@@ -288,10 +289,12 @@
   return ret_value;
 }
 
-void DeckLinkCaptureDelegate::SendErrorString(const std::string& reason) {
+void DeckLinkCaptureDelegate::SendErrorString(
+    const tracked_objects::Location& from_here,
+    const std::string& reason) {
   base::AutoLock lock(lock_);
   if (frame_receiver_)
-    frame_receiver_->SendErrorString(reason);
+    frame_receiver_->SendErrorString(from_here, reason);
 }
 
 void DeckLinkCaptureDelegate::SendLogString(const std::string& message) {
@@ -453,11 +456,13 @@
   }
 }
 
-void VideoCaptureDeviceDeckLinkMac::SendErrorString(const std::string& reason) {
+void VideoCaptureDeviceDeckLinkMac::SendErrorString(
+    const tracked_objects::Location& from_here,
+    const std::string& reason) {
   DCHECK(thread_checker_.CalledOnValidThread());
   base::AutoLock lock(lock_);
   if (client_)
-    client_->OnError(reason);
+    client_->OnError(from_here, reason);
 }
 
 void VideoCaptureDeviceDeckLinkMac::SendLogString(const std::string& message) {
diff --git a/media/capture/video/mac/video_capture_device_mac.h b/media/capture/video/mac/video_capture_device_mac.h
index c36248e..1b91c87 100644
--- a/media/capture/video/mac/video_capture_device_mac.h
+++ b/media/capture/video/mac/video_capture_device_mac.h
@@ -27,6 +27,10 @@
 class SingleThreadTaskRunner;
 }
 
+namespace tracked_objects {
+class Location;
+}  // namespace tracked_objects
+
 // Small class to bundle device name and connection type into a dictionary.
 MEDIA_EXPORT
 @interface DeviceNameAndTransportType : NSObject {
@@ -73,13 +77,15 @@
                     int aspect_denominator);
 
   // Forwarder to VideoCaptureDevice::Client::OnError().
-  void ReceiveError(const std::string& reason);
+  void ReceiveError(const tracked_objects::Location& from_here,
+                    const std::string& reason);
 
   // Forwarder to VideoCaptureDevice::Client::OnLog().
   void LogMessage(const std::string& message);
 
  private:
-  void SetErrorState(const std::string& reason);
+  void SetErrorState(const tracked_objects::Location& from_here,
+                     const std::string& reason);
   bool UpdateCaptureResolution();
 
   // Flag indicating the internal state.
diff --git a/media/capture/video/mac/video_capture_device_mac.mm b/media/capture/video/mac/video_capture_device_mac.mm
index 5fc083e..cc8608e 100644
--- a/media/capture/video/mac/video_capture_device_mac.mm
+++ b/media/capture/video/mac/video_capture_device_mac.mm
@@ -381,7 +381,7 @@
   [capture_device_ setFrameReceiver:this];
 
   if (![capture_device_ setCaptureDevice:deviceId]) {
-    SetErrorState("Could not open capture device.");
+    SetErrorState(FROM_HERE, "Could not open capture device.");
     return;
   }
 
@@ -422,7 +422,7 @@
   }
 
   if (![capture_device_ startCapture]) {
-    SetErrorState("Could not start capture device.");
+    SetErrorState(FROM_HERE, "Could not start capture device.");
     return;
   }
 
@@ -530,8 +530,9 @@
   if (!AVFoundationGlue::IsAVFoundationSupported()) {
     capture_format_.frame_size = frame_format.frame_size;
   } else if (capture_format_.frame_size != frame_format.frame_size) {
-    ReceiveError("Captured resolution " + frame_format.frame_size.ToString() +
-                 ", and expected " + capture_format_.frame_size.ToString());
+    ReceiveError(FROM_HERE,
+                 "Captured resolution " + frame_format.frame_size.ToString() +
+                     ", and expected " + capture_format_.frame_size.ToString());
     return;
   }
 
@@ -539,16 +540,20 @@
                                   0, base::TimeTicks::Now());
 }
 
-void VideoCaptureDeviceMac::ReceiveError(const std::string& reason) {
-  task_runner_->PostTask(FROM_HERE,
-                         base::Bind(&VideoCaptureDeviceMac::SetErrorState,
-                                    weak_factory_.GetWeakPtr(), reason));
+void VideoCaptureDeviceMac::ReceiveError(
+    const tracked_objects::Location& from_here,
+    const std::string& reason) {
+  task_runner_->PostTask(
+      FROM_HERE, base::Bind(&VideoCaptureDeviceMac::SetErrorState,
+                            weak_factory_.GetWeakPtr(), from_here, reason));
 }
 
-void VideoCaptureDeviceMac::SetErrorState(const std::string& reason) {
+void VideoCaptureDeviceMac::SetErrorState(
+    const tracked_objects::Location& from_here,
+    const std::string& reason) {
   DCHECK(task_runner_->BelongsToCurrentThread());
   state_ = kError;
-  client_->OnError(reason);
+  client_->OnError(from_here, reason);
 }
 
 void VideoCaptureDeviceMac::LogMessage(const std::string& message) {
@@ -561,7 +566,7 @@
   if (![capture_device_ setCaptureHeight:capture_format_.frame_size.height()
                                    width:capture_format_.frame_size.width()
                                frameRate:capture_format_.frame_rate]) {
-    ReceiveError("Could not configure capture device.");
+    ReceiveError(FROM_HERE, "Could not configure capture device.");
     return false;
   }
   return true;
diff --git a/media/capture/video/mac/video_capture_device_qtkit_mac.mm b/media/capture/video/mac/video_capture_device_qtkit_mac.mm
index 1ea4c9e4..9218a11 100644
--- a/media/capture/video/mac/video_capture_device_qtkit_mac.mm
+++ b/media/capture/video/mac/video_capture_device_qtkit_mac.mm
@@ -7,6 +7,7 @@
 #import <QTKit/QTKit.h>
 
 #include "base/debug/crash_logging.h"
+#include "base/location.h"
 #include "base/logging.h"
 #include "media/base/video_capture_types.h"
 #include "media/capture/video/mac/video_capture_device_mac.h"
@@ -345,7 +346,7 @@
   DLOG(ERROR) << [error UTF8String];
   [lock_ lock];
   if (frameReceiver_)
-    frameReceiver_->ReceiveError([error UTF8String]);
+    frameReceiver_->ReceiveError(FROM_HERE, [error UTF8String]);
   [lock_ unlock];
 }
 
diff --git a/media/capture/video/video_capture_device.h b/media/capture/video/video_capture_device.h
index ad0927d..099cf28 100644
--- a/media/capture/video/video_capture_device.h
+++ b/media/capture/video/video_capture_device.h
@@ -26,6 +26,10 @@
 #include "media/base/video_frame.h"
 #include "ui/gfx/gpu_memory_buffer.h"
 
+namespace tracked_objects {
+class Location;
+}  // namespace tracked_objects
+
 namespace media {
 
 class MEDIA_EXPORT VideoCaptureDevice {
@@ -250,7 +254,8 @@
 
     // An error has occurred that cannot be handled and VideoCaptureDevice must
     // be StopAndDeAllocate()-ed. |reason| is a text description of the error.
-    virtual void OnError(const std::string& reason) = 0;
+    virtual void OnError(const tracked_objects::Location& from_here,
+                         const std::string& reason) = 0;
 
     // VideoCaptureDevice requests the |message| to be logged.
     virtual void OnLog(const std::string& message) {}
diff --git a/media/capture/video/video_capture_device_unittest.cc b/media/capture/video/video_capture_device_unittest.cc
index 3b951f3e..e907bf60 100644
--- a/media/capture/video/video_capture_device_unittest.cc
+++ b/media/capture/video/video_capture_device_unittest.cc
@@ -78,7 +78,9 @@
   MOCK_METHOD0(DoReserveOutputBuffer, void(void));
   MOCK_METHOD0(DoOnIncomingCapturedBuffer, void(void));
   MOCK_METHOD0(DoOnIncomingCapturedVideoFrame, void(void));
-  MOCK_METHOD1(OnError, void(const std::string& reason));
+  MOCK_METHOD2(OnError,
+               void(const tracked_objects::Location& from_here,
+                    const std::string& reason));
   MOCK_CONST_METHOD0(GetBufferPoolUtilization, double(void));
 
   explicit MockClient(base::Callback<void(const VideoCaptureFormat&)> frame_cb)
@@ -280,7 +282,7 @@
   } else {
     // The presence of the actual device is only checked on AllocateAndStart()
     // and not on creation for QTKit API in Mac OS X platform.
-    EXPECT_CALL(*client_, OnError(_)).Times(1);
+    EXPECT_CALL(*client_, OnError(_, _)).Times(1);
 
     VideoCaptureParams capture_params;
     capture_params.requested_format.frame_size.SetSize(640, 480);
@@ -310,7 +312,7 @@
   ASSERT_TRUE(device);
   DVLOG(1) << names_->front().id();
 
-  EXPECT_CALL(*client_, OnError(_)).Times(0);
+  EXPECT_CALL(*client_, OnError(_, _)).Times(0);
 
   VideoCaptureParams capture_params;
   capture_params.requested_format.frame_size.SetSize(width, height);
@@ -343,7 +345,7 @@
       video_capture_device_factory_->Create(names_->front()));
   ASSERT_TRUE(device);
 
-  EXPECT_CALL(*client_, OnError(_)).Times(0);
+  EXPECT_CALL(*client_, OnError(_, _)).Times(0);
 
   const gfx::Size input_size(640, 480);
   VideoCaptureParams capture_params;
@@ -415,7 +417,7 @@
       video_capture_device_factory_->Create(names_->front()));
   ASSERT_TRUE(device);
 
-  EXPECT_CALL(*client_, OnError(_)).Times(0);
+  EXPECT_CALL(*client_, OnError(_, _)).Times(0);
 
   VideoCaptureParams capture_params;
   capture_params.requested_format.frame_size.SetSize(640, 480);
@@ -442,7 +444,7 @@
       video_capture_device_factory_->Create(*name));
   ASSERT_TRUE(device);
 
-  EXPECT_CALL(*client_, OnError(_)).Times(0);
+  EXPECT_CALL(*client_, OnError(_, _)).Times(0);
 
   VideoCaptureParams capture_params;
   capture_params.requested_format.frame_size.SetSize(1280, 720);
diff --git a/media/capture/video/win/video_capture_device_mf_win.cc b/media/capture/video/win/video_capture_device_mf_win.cc
index c55cf4aa..95595bd 100644
--- a/media/capture/video/win/video_capture_device_mf_win.cc
+++ b/media/capture/video/win/video_capture_device_mf_win.cc
@@ -7,6 +7,7 @@
 #include <mfapi.h>
 #include <mferror.h>
 
+#include "base/location.h"
 #include "base/memory/ref_counted.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/sys_string_conversions.h"
@@ -260,7 +261,7 @@
     }
   }
 
-  OnError(hr);
+  OnError(FROM_HERE, hr);
 }
 
 void VideoCaptureDeviceMFWin::StopAndDeAllocate() {
@@ -311,14 +312,17 @@
       // It's not clear to me why this is, but it is possible that it has
       // something to do with this bug:
       // http://support.microsoft.com/kb/979567
-      OnError(hr);
+      OnError(FROM_HERE, hr);
     }
   }
 }
 
-void VideoCaptureDeviceMFWin::OnError(HRESULT hr) {
+void VideoCaptureDeviceMFWin::OnError(
+    const tracked_objects::Location& from_here,
+    HRESULT hr) {
   if (client_.get()) {
     client_->OnError(
+        from_here,
         base::StringPrintf("VideoCaptureDeviceMFWin: %s",
                            logging::SystemErrorCodeToString(hr).c_str()));
   }
diff --git a/media/capture/video/win/video_capture_device_mf_win.h b/media/capture/video/win/video_capture_device_mf_win.h
index 7894864..bcc9c1f 100644
--- a/media/capture/video/win/video_capture_device_mf_win.h
+++ b/media/capture/video/win/video_capture_device_mf_win.h
@@ -22,6 +22,10 @@
 
 interface IMFSourceReader;
 
+namespace tracked_objects {
+class Location;
+}  // namespace tracked_objects
+
 namespace media {
 
 class MFReaderCallback;
@@ -52,7 +56,7 @@
                               const base::TimeTicks& time_stamp);
 
  private:
-  void OnError(HRESULT hr);
+  void OnError(const tracked_objects::Location& from_here, HRESULT hr);
 
   Name name_;
   base::win::ScopedComPtr<IMFActivate> device_;
diff --git a/media/capture/video/win/video_capture_device_win.cc b/media/capture/video/win/video_capture_device_win.cc
index 9960406..92ee2a5 100644
--- a/media/capture/video/win/video_capture_device_win.cc
+++ b/media/capture/video/win/video_capture_device_win.cc
@@ -348,14 +348,14 @@
   ScopedComPtr<IAMStreamConfig> stream_config;
   HRESULT hr = output_capture_pin_.QueryInterface(stream_config.Receive());
   if (FAILED(hr)) {
-    SetErrorState("Can't get the Capture format settings");
+    SetErrorState(FROM_HERE, "Can't get the Capture format settings");
     return;
   }
 
   int count = 0, size = 0;
   hr = stream_config->GetNumberOfCapabilities(&count, &size);
   if (FAILED(hr)) {
-    SetErrorState("Failed to GetNumberOfCapabilities");
+    SetErrorState(FROM_HERE, "Failed to GetNumberOfCapabilities");
     return;
   }
 
@@ -368,7 +368,7 @@
   hr = stream_config->GetStreamCaps(found_capability.stream_index,
                                     media_type.Receive(), caps.get());
   if (hr != S_OK) {
-    SetErrorState("Failed to get capture device capabilities");
+    SetErrorState(FROM_HERE, "Failed to get capture device capabilities");
     return;
   }
   if (media_type->formattype == FORMAT_VideoInfo) {
@@ -385,7 +385,7 @@
   hr = stream_config->SetFormat(media_type.get());
   if (FAILED(hr)) {
     // TODO(grunell): Log the error. http://crbug.com/405016.
-    SetErrorState("Failed to set capture device output format");
+    SetErrorState(FROM_HERE, "Failed to set capture device output format");
     return;
   }
 
@@ -402,13 +402,14 @@
   }
 
   if (FAILED(hr)) {
-    SetErrorState("Failed to connect the Capture graph.");
+    SetErrorState(FROM_HERE, "Failed to connect the Capture graph.");
     return;
   }
 
   hr = media_control_->Pause();
   if (FAILED(hr)) {
     SetErrorState(
+        FROM_HERE,
         "Failed to pause the Capture device, is it already occupied?");
     return;
   }
@@ -420,7 +421,7 @@
   // Start capturing.
   hr = media_control_->Run();
   if (FAILED(hr)) {
-    SetErrorState("Failed to start the Capture device.");
+    SetErrorState(FROM_HERE, "Failed to start the Capture device.");
     return;
   }
 
@@ -434,7 +435,7 @@
 
   HRESULT hr = media_control_->Stop();
   if (FAILED(hr)) {
-    SetErrorState("Failed to stop the capture graph.");
+    SetErrorState(FROM_HERE, "Failed to stop the capture graph.");
     return;
   }
 
@@ -572,9 +573,11 @@
   }
 }
 
-void VideoCaptureDeviceWin::SetErrorState(const std::string& reason) {
+void VideoCaptureDeviceWin::SetErrorState(
+    const tracked_objects::Location& from_here,
+    const std::string& reason) {
   DCHECK(thread_checker_.CalledOnValidThread());
   state_ = kError;
-  client_->OnError(reason);
+  client_->OnError(from_here, reason);
 }
 }  // namespace media
diff --git a/media/capture/video/win/video_capture_device_win.h b/media/capture/video/win/video_capture_device_win.h
index dec02c1..6bd0eb4 100644
--- a/media/capture/video/win/video_capture_device_win.h
+++ b/media/capture/video/win/video_capture_device_win.h
@@ -23,6 +23,10 @@
 #include "media/capture/video/win/sink_filter_win.h"
 #include "media/capture/video/win/sink_input_pin_win.h"
 
+namespace tracked_objects {
+class Location;
+}  // namespace tracked_objects
+
 namespace media {
 
 // All the methods in the class can only be run on a COM initialized thread.
@@ -82,7 +86,8 @@
 
   bool CreateCapabilityMap();
   void SetAntiFlickerInCaptureFilter(const VideoCaptureParams& params);
-  void SetErrorState(const std::string& reason);
+  void SetErrorState(const tracked_objects::Location& from_here,
+                     const std::string& reason);
 
   const Name device_name_;
   InternalState state_;