Several minor improvements of DirectX capturer
1. It looks like ComPtr cannot work well with vector::emplace_back, I got a
consistent crash on one of my machine, but not the other. Move constructor
should have no impact to lvalue reference, but I may be wrong here. The
impact here is ComPtr released before it should be. So a simple solution is to
use copy instead of reference. The D3dDevice is a collection of reference
counted pointers (Microsoft::WRL::ComPtr), there is almost no extra cost.

2. Actively set several fields in D3D11_TEXTURE2D_DESC to avoid potential break
if there are some platform changes later.

3. AcquireNextFrame returns both a DXGI_OUTDUPL_FRAME_INFO with
AccumulatedFrames and an IDXGIResource. But there is no comment in MSDN to
ensure IDXGIResource won't be nullptr if AccumulatedFrames > 0. Adding an extra
check in DxgiOutputDuplicator makes it a safer.

BUG=314516

Review-Url: https://codereview.webrtc.org/2345163002
Cr-Commit-Position: refs/heads/master@{#14341}
diff --git a/webrtc/modules/desktop_capture/win/d3d_device.cc b/webrtc/modules/desktop_capture/win/d3d_device.cc
index 15233e6..f7c419f 100644
--- a/webrtc/modules/desktop_capture/win/d3d_device.cc
+++ b/webrtc/modules/desktop_capture/win/d3d_device.cc
@@ -47,7 +47,7 @@
     return false;
   }
 
-  error = _com_error(d3d_device_.As(&dxgi_device_));
+  error = d3d_device_.As(&dxgi_device_);
   if (error.Error() != S_OK || !dxgi_device_) {
     LOG(LS_WARNING) << "ID3D11Device is not an implementation of IDXGIDevice, "
                        "this usually means the system does not support DirectX "
@@ -61,9 +61,8 @@
 // static
 std::vector<D3dDevice> D3dDevice::EnumDevices() {
   ComPtr<IDXGIFactory1> factory;
-  _com_error error = _com_error(
-      CreateDXGIFactory1(__uuidof(IDXGIFactory1),
-                         reinterpret_cast<void**>(factory.GetAddressOf())));
+  _com_error error = CreateDXGIFactory1(__uuidof(IDXGIFactory1),
+      reinterpret_cast<void**>(factory.GetAddressOf()));
   if (error.Error() != S_OK || !factory) {
     return std::vector<D3dDevice>();
   }
@@ -71,7 +70,7 @@
   std::vector<D3dDevice> result;
   for (int i = 0;; i++) {
     ComPtr<IDXGIAdapter> adapter;
-    error = _com_error(factory->EnumAdapters(i, adapter.GetAddressOf()));
+    error = factory->EnumAdapters(i, adapter.GetAddressOf());
     if (error.Error() == S_OK) {
       D3dDevice device;
       if (!device.Initialize(adapter)) {
diff --git a/webrtc/modules/desktop_capture/win/d3d_device.h b/webrtc/modules/desktop_capture/win/d3d_device.h
index 94a263e..fc1533a 100644
--- a/webrtc/modules/desktop_capture/win/d3d_device.h
+++ b/webrtc/modules/desktop_capture/win/d3d_device.h
@@ -43,7 +43,7 @@
   // function.
   D3dDevice();
 
-  // Initialize the D3dDevice from an IDXGIAdapter.
+  // Initializes the D3dDevice from an IDXGIAdapter.
   bool Initialize(const Microsoft::WRL::ComPtr<IDXGIAdapter>& adapter);
 
   Microsoft::WRL::ComPtr<ID3D11Device> d3d_device_;
diff --git a/webrtc/modules/desktop_capture/win/dxgi_adapter_duplicator.cc b/webrtc/modules/desktop_capture/win/dxgi_adapter_duplicator.cc
index 1b82216..46d4e89 100644
--- a/webrtc/modules/desktop_capture/win/dxgi_adapter_duplicator.cc
+++ b/webrtc/modules/desktop_capture/win/dxgi_adapter_duplicator.cc
@@ -62,11 +62,11 @@
     }
 
     DXGI_OUTPUT_DESC desc;
-    error = _com_error(output->GetDesc(&desc));
+    error = output->GetDesc(&desc);
     if (error.Error() == S_OK) {
       if (desc.AttachedToDesktop && IsValidRect(desc.DesktopCoordinates)) {
         ComPtr<IDXGIOutput1> output1;
-        error = _com_error(output.As(&output1));
+        error = output.As(&output1);
         if (error.Error() != S_OK || !output1) {
           LOG(LS_WARNING) << "Failed to convert IDXGIOutput to IDXGIOutput1, "
                              "this usually means the system does not support "
diff --git a/webrtc/modules/desktop_capture/win/dxgi_output_duplicator.cc b/webrtc/modules/desktop_capture/win/dxgi_output_duplicator.cc
index d7eb335..b17c195 100644
--- a/webrtc/modules/desktop_capture/win/dxgi_output_duplicator.cc
+++ b/webrtc/modules/desktop_capture/win/dxgi_output_duplicator.cc
@@ -147,7 +147,9 @@
   // after it has been merged to updated_region.
   DesktopRegion updated_region;
   updated_region.Swap(&context->updated_region);
-  if (error.Error() == S_OK && frame_info.AccumulatedFrames > 0) {
+  if (error.Error() == S_OK &&
+      frame_info.AccumulatedFrames > 0 &&
+      resource) {
     DetectUpdatedRegion(frame_info, offset, &context->updated_region);
     if (!texture_->CopyFrom(frame_info, resource.Get(),
                             context->updated_region)) {
@@ -224,8 +226,8 @@
   DXGI_OUTDUPL_MOVE_RECT* move_rects =
       reinterpret_cast<DXGI_OUTDUPL_MOVE_RECT*>(metadata.data());
   size_t move_rects_count = 0;
-  _com_error error = _com_error(duplication_->GetFrameMoveRects(
-      static_cast<UINT>(metadata.capacity()), move_rects, &buff_size));
+  _com_error error = duplication_->GetFrameMoveRects(
+      static_cast<UINT>(metadata.capacity()), move_rects, &buff_size);
   if (error.Error() != S_OK) {
     LOG(LS_ERROR) << "Failed to get move rectangles, error "
                   << error.ErrorMessage() << ", code " << error.Error();
@@ -235,9 +237,9 @@
 
   RECT* dirty_rects = reinterpret_cast<RECT*>(metadata.data() + buff_size);
   size_t dirty_rects_count = 0;
-  error = _com_error(duplication_->GetFrameDirtyRects(
+  error = duplication_->GetFrameDirtyRects(
       static_cast<UINT>(metadata.capacity()) - buff_size, dirty_rects,
-      &buff_size));
+      &buff_size);
   if (error.Error() != S_OK) {
     LOG(LS_ERROR) << "Failed to get dirty rectangles, error "
                   << error.ErrorMessage() << ", code " << error.Error();
diff --git a/webrtc/modules/desktop_capture/win/dxgi_output_duplicator.h b/webrtc/modules/desktop_capture/win/dxgi_output_duplicator.h
index 020ca64..0d5b134 100644
--- a/webrtc/modules/desktop_capture/win/dxgi_output_duplicator.h
+++ b/webrtc/modules/desktop_capture/win/dxgi_output_duplicator.h
@@ -111,7 +111,7 @@
   // Returns a DesktopRect in the coordinate of |offset|.
   DesktopRect TargetRect(DesktopRect rect, DesktopVector offset);
 
-  const D3dDevice& device_;
+  const D3dDevice device_;
   const Microsoft::WRL::ComPtr<IDXGIOutput1> output_;
   const DesktopRect desktop_rect_;
   Microsoft::WRL::ComPtr<IDXGIOutputDuplication> duplication_;
diff --git a/webrtc/modules/desktop_capture/win/dxgi_texture_staging.cc b/webrtc/modules/desktop_capture/win/dxgi_texture_staging.cc
index 7478728..6866d1e 100644
--- a/webrtc/modules/desktop_capture/win/dxgi_texture_staging.cc
+++ b/webrtc/modules/desktop_capture/win/dxgi_texture_staging.cc
@@ -38,9 +38,13 @@
     return false;
   }
 
+  desc.ArraySize = 1;
   desc.BindFlags = 0;
   desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+  desc.MipLevels = 1;
   desc.MiscFlags = 0;
+  desc.SampleDesc.Count = 1;
+  desc.SampleDesc.Quality = 0;
   desc.Usage = D3D11_USAGE_STAGING;
   if (stage_) {
     AssertStageAndSurfaceAreSameObject();
@@ -58,15 +62,15 @@
     RTC_DCHECK(!surface_);
   }
 
-  _com_error error = _com_error(device_.d3d_device()->CreateTexture2D(
-      &desc, nullptr, stage_.GetAddressOf()));
+  _com_error error = device_.d3d_device()->CreateTexture2D(
+      &desc, nullptr, stage_.GetAddressOf());
   if (error.Error() != S_OK || !stage_) {
     LOG(LS_ERROR) << "Failed to create a new ID3D11Texture2D as stage, error "
                   << error.ErrorMessage() << ", code " << error.Error();
     return false;
   }
 
-  error = _com_error(stage_.As(&surface_));
+  error = stage_.As(&surface_);
   if (error.Error() != S_OK || !surface_) {
     LOG(LS_ERROR) << "Failed to convert ID3D11Texture2D to IDXGISurface, error "
                   << error.ErrorMessage() << ", code " << error.Error();
@@ -123,7 +127,7 @@
   }
 
   rect_ = {0};
-  error = _com_error(surface_->Map(&rect_, DXGI_MAP_READ));
+  error = surface_->Map(&rect_, DXGI_MAP_READ);
   if (error.Error() != S_OK) {
     rect_ = {0};
     LOG(LS_ERROR) << "Failed to map the IDXGISurface to a bitmap, error "
@@ -135,7 +139,7 @@
 }
 
 bool DxgiTextureStaging::DoRelease() {
-  _com_error error = _com_error(surface_->Unmap());
+  _com_error error = surface_->Unmap();
   if (error.Error() != S_OK) {
     stage_.Reset();
     surface_.Reset();
diff --git a/webrtc/modules/desktop_capture/win/dxgi_texture_staging.h b/webrtc/modules/desktop_capture/win/dxgi_texture_staging.h
index 2da1600..47f75fa 100644
--- a/webrtc/modules/desktop_capture/win/dxgi_texture_staging.h
+++ b/webrtc/modules/desktop_capture/win/dxgi_texture_staging.h
@@ -58,7 +58,7 @@
   void AssertStageAndSurfaceAreSameObject();
 
   const DesktopRect desktop_rect_;
-  const D3dDevice& device_;
+  const D3dDevice device_;
   Microsoft::WRL::ComPtr<ID3D11Texture2D> stage_;
   Microsoft::WRL::ComPtr<IDXGISurface> surface_;
 };