winscreencap: Remove dxgiscreencapsrc element
authorSeungha Yang <seungha@centricular.com>
Sat, 19 Feb 2022 21:36:45 +0000 (06:36 +0900)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Sun, 20 Feb 2022 20:04:05 +0000 (20:04 +0000)
We have the d3d11screencapturesrc element in d3d11 plugin
which is obviously better than this element in terms of performance
and design, so we don't need to make people be confused by two separate elements.

Let's pick the better implementation and remove unnecessary one.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1750>

subprojects/gst-plugins-bad/sys/winscreencap/dxgicapture.c [deleted file]
subprojects/gst-plugins-bad/sys/winscreencap/dxgicapture.h [deleted file]
subprojects/gst-plugins-bad/sys/winscreencap/gstdxgiscreencapsrc.c [deleted file]
subprojects/gst-plugins-bad/sys/winscreencap/gstdxgiscreencapsrc.h [deleted file]
subprojects/gst-plugins-bad/sys/winscreencap/gstwinscreencap.c
subprojects/gst-plugins-bad/sys/winscreencap/meson.build

diff --git a/subprojects/gst-plugins-bad/sys/winscreencap/dxgicapture.c b/subprojects/gst-plugins-bad/sys/winscreencap/dxgicapture.c
deleted file mode 100644 (file)
index 92373bc..0000000
+++ /dev/null
@@ -1,1421 +0,0 @@
-/* GStreamer
- * Copyright (C) 2019 OKADA Jun-ichi <okada@abt.jp>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-/* This code captures the screen using "Desktop Duplication API".
- * For more information
- * https://docs.microsoft.com/en-us/windows/win32/direct3ddxgi/desktop-dup-api */
-
-#include "dxgicapture.h"
-
-#include <d3dcompiler.h>
-#include <gmodule.h>
-
-GST_DEBUG_CATEGORY_EXTERN (gst_dxgi_screen_cap_src_debug);
-#define GST_CAT_DEFAULT gst_dxgi_screen_cap_src_debug
-
-#define PTR_RELEASE(p) {if(NULL!=(p)){IUnknown_Release((IUnknown *)(p)); (p) = NULL;}}
-#define BYTE_PER_PIXEL (4)
-
-/* vertex structures */
-typedef struct _vector3d
-{
-  float x;
-  float y;
-  float z;
-} vector3d;
-
-typedef struct _vector2d
-{
-  float x;
-  float y;
-} vector2d;
-
-typedef struct _vertex
-{
-  vector3d pos;
-  vector2d texcoord;
-} vertex;
-#define VERTEX_NUM (6);
-
-typedef struct _DxgiCapture
-{
-  GstDXGIScreenCapSrc *src;
-
-  /*Direct3D pointers */
-  ID3D11Device *d3d11_device;
-  ID3D11DeviceContext *d3d11_context;
-  IDXGIOutput1 *dxgi_output1;
-  IDXGIOutputDuplication *dxgi_dupl;
-
-  /* Texture that has been rotated and combined fragments. */
-  ID3D11Texture2D *work_texture;
-  D3D11_TEXTURE2D_DESC work_texture_desc;
-  D3D11_VIEWPORT view_port;
-  /* Textures that can be read by the CPU.
-   * CPU-accessible textures are required separately from work_texture
-   * because shaders cannot be executed. */
-  ID3D11Texture2D *readable_texture;
-  ID3D11VertexShader *vertex_shader;
-  ID3D11PixelShader *pixel_shader;
-  ID3D11SamplerState *sampler_state;
-  ID3D11RenderTargetView *target_view;
-  /* Screen output dimensions and rotation status.
-   * The texture acquired by AcquireNextFrame has a non-rotated region. */
-  DXGI_OUTDUPL_DESC dupl_desc;
-
-  /* mouse pointer image */
-  guint8 *pointer_buffer;
-  gsize pointer_buffer_capacity;
-
-  /* The movement rectangular regions and the movement
-   * destination position from the previous frame. */
-  DXGI_OUTDUPL_MOVE_RECT *move_rects;
-  gsize move_rects_capacity;
-
-  /* Array of dirty rectangular region for the desktop frame. */
-  RECT *dirty_rects;
-  gsize dirty_rects_capacity;
-
-  /* Vertex buffer created from array of dirty rectangular region. */
-  vertex *dirty_verteces;
-  gsize verteces_capacity;
-
-  /* Array of rectangular region to copy to readable_texture. */
-  RECT *copy_rects;
-  gsize copy_rects_capacity;
-
-  /* latest mouse pointer info */
-  DXGI_OUTDUPL_POINTER_SHAPE_INFO pointer_shape_info;
-  DXGI_OUTDUPL_POINTER_POSITION last_pointer_position;
-
-} DxgiCapture;
-
-/* Vertex shader for texture rotation by HLSL. */
-static const char STR_VERTEX_SHADER[] =
-    "struct vs_input  { float4 pos : POSITION; float2 tex : TEXCOORD; }; "
-    "struct vs_output { float4 pos : SV_POSITION; float2 tex : TEXCOORD; }; "
-    "vs_output vs_main(vs_input input){return input;}";
-
-/* Pixel shader for texture rotation by HLSL. */
-static const char STR_PIXEL_SHADER[] =
-    "Texture2D tx : register( t0 ); "
-    "SamplerState samp : register( s0 ); "
-    "struct ps_input { float4 pos : SV_POSITION; float2 tex : TEXCOORD;}; "
-    "float4 ps_main(ps_input input) : "
-    "SV_Target{ return tx.Sample( samp, input.tex ); }";
-
-/* initial buffer size */
-const int INITIAL_POINTER_BUFFER_CAPACITY = 64 * 64 * BYTE_PER_PIXEL;
-const int INITIAL_MOVE_RECTS_CAPACITY = 100;
-const int INITIAL_DIRTY_RECTS_CAPACITY = 100;
-const int INITIAL_VERTICES_CAPACITY = 100 * VERTEX_NUM;
-const int INITIAL_COPY_RECTS_CAPACITY = 100;
-
-static D3D_FEATURE_LEVEL feature_levels[] = {
-  D3D_FEATURE_LEVEL_11_0,
-  D3D_FEATURE_LEVEL_10_1,
-  D3D_FEATURE_LEVEL_10_0,
-  D3D_FEATURE_LEVEL_9_3,
-  D3D_FEATURE_LEVEL_9_2,
-  D3D_FEATURE_LEVEL_9_1,
-};
-
-static D3D11_INPUT_ELEMENT_DESC vertex_layout[] = {
-  {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,
-      D3D11_INPUT_PER_VERTEX_DATA, 0},
-  {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA,
-      0}
-};
-
-static void _draw_pointer (DxgiCapture * self, LPBYTE buffer, LPRECT dst_rect,
-    int stride);
-static ID3D11Texture2D *_create_texture (DxgiCapture * self,
-    enum D3D11_USAGE usage, UINT bindFlags, UINT cpuAccessFlags);
-
-static gboolean _setup_texture (DxgiCapture * self);
-
-static HRESULT _update_work_texture (DxgiCapture * self,
-    IDXGIResource * desktop_resource);
-
-static HRESULT _copy_dirty_fragment (DxgiCapture * self,
-    ID3D11Texture2D * src_texture, const D3D11_TEXTURE2D_DESC * src_desc,
-    guint move_count, guint dirty_count, RECT ** dst_rect);
-
-static void _set_verteces (DxgiCapture * self, vertex * verteces,
-    RECT * dest_rect, const D3D11_TEXTURE2D_DESC * dst_desc, RECT * rect,
-    const D3D11_TEXTURE2D_DESC * src_desc);
-
-static GModule *d3d_compiler_module = NULL;
-static pD3DCompile GstD3DCompileFunc = NULL;
-
-gboolean
-gst_dxgicap_shader_init (void)
-{
-  static gsize _init = 0;
-  static const gchar *d3d_compiler_names[] = {
-    "d3dcompiler_47.dll",
-    "d3dcompiler_46.dll",
-    "d3dcompiler_45.dll",
-    "d3dcompiler_44.dll",
-    "d3dcompiler_43.dll",
-  };
-
-  if (g_once_init_enter (&_init)) {
-    gint i;
-    for (i = 0; i < G_N_ELEMENTS (d3d_compiler_names); i++) {
-      d3d_compiler_module =
-          g_module_open (d3d_compiler_names[i], G_MODULE_BIND_LAZY);
-
-      if (d3d_compiler_module) {
-        GST_INFO ("D3D compiler %s is available", d3d_compiler_names[i]);
-        if (!g_module_symbol (d3d_compiler_module, "D3DCompile",
-                (gpointer *) & GstD3DCompileFunc)) {
-          GST_ERROR ("Cannot load D3DCompile symbol from %s",
-              d3d_compiler_names[i]);
-          g_module_close (d3d_compiler_module);
-          d3d_compiler_module = NULL;
-          GstD3DCompileFunc = NULL;
-        } else {
-          break;
-        }
-      }
-    }
-
-    if (!GstD3DCompileFunc)
-      GST_WARNING ("D3D11 compiler library is unavailable");
-
-    g_once_init_leave (&_init, 1);
-  }
-
-  return ! !GstD3DCompileFunc;
-}
-
-static GstFlowReturn
-initialize_output_duplication (DxgiCapture * self)
-{
-  HDESK hdesk;
-  HRESULT hr;
-  DXGI_OUTDUPL_DESC old_dupl_desc;
-  GstDXGIScreenCapSrc *src = self->src;
-
-  PTR_RELEASE (self->dxgi_dupl);
-
-  hdesk = OpenInputDesktop (0, FALSE, GENERIC_ALL);
-  if (hdesk) {
-    if (!SetThreadDesktop (hdesk)) {
-      GST_WARNING_OBJECT (src, "SetThreadDesktop() failed. Error code: %lu",
-          GetLastError ());
-    }
-
-    CloseDesktop (hdesk);
-  } else {
-    GST_WARNING_OBJECT (src, "OpenInputDesktop() failed. Error code: %lu",
-        GetLastError ());
-  }
-
-  hr = IDXGIOutput1_DuplicateOutput (self->dxgi_output1,
-      (IUnknown *) (self->d3d11_device), &self->dxgi_dupl);
-  if (hr != S_OK) {
-    gchar *msg = get_hresult_to_string (hr);
-    GST_WARNING_OBJECT (src, "IDXGIOutput1::DuplicateOutput() failed (%x): %s",
-        (guint) hr, msg);
-    g_free (msg);
-    if (hr == E_ACCESSDENIED) {
-      /* Happens temporarily during resolution changes. */
-      return GST_FLOW_OK;
-    }
-    return GST_FLOW_ERROR;
-  }
-
-  old_dupl_desc = self->dupl_desc;
-  IDXGIOutputDuplication_GetDesc (self->dxgi_dupl, &self->dupl_desc);
-
-  if (self->readable_texture &&
-      (self->dupl_desc.ModeDesc.Width != old_dupl_desc.ModeDesc.Width ||
-          self->dupl_desc.ModeDesc.Height != old_dupl_desc.ModeDesc.Height ||
-          self->dupl_desc.Rotation != old_dupl_desc.Rotation)) {
-    PTR_RELEASE (self->readable_texture);
-    PTR_RELEASE (self->work_texture);
-
-    _setup_texture (self);
-
-    return GST_DXGICAP_FLOW_RESOLUTION_CHANGE;
-  }
-
-  return GST_FLOW_OK;
-}
-
-DxgiCapture *
-dxgicap_new (HMONITOR monitor, GstDXGIScreenCapSrc * src)
-{
-  int i, j;
-  HRESULT hr;
-  IDXGIFactory1 *dxgi_factory1 = NULL;
-  IDXGIAdapter1 *dxgi_adapter1 = NULL;
-  ID3D11InputLayout *vertex_input_layout = NULL;
-  ID3DBlob *vertex_shader_blob = NULL;
-  ID3DBlob *pixel_shader_blob = NULL;
-  D3D11_SAMPLER_DESC sampler_desc;
-
-  DxgiCapture *self = g_new0 (DxgiCapture, 1);
-  if (NULL == self) {
-    return NULL;
-  }
-
-  self->src = src;
-  hr = CreateDXGIFactory1 (&IID_IDXGIFactory1, (void **) &dxgi_factory1);
-  HR_FAILED_GOTO (hr, CreateDXGIFactory1, new_error);
-
-  for (i = 0;
-      IDXGIFactory1_EnumAdapters1 (dxgi_factory1, i,
-          &dxgi_adapter1) != DXGI_ERROR_NOT_FOUND; ++i) {
-    IDXGIOutput *dxgi_output = NULL;
-    D3D_FEATURE_LEVEL feature_level;
-
-    hr = D3D11CreateDevice ((IDXGIAdapter *) dxgi_adapter1,
-        D3D_DRIVER_TYPE_UNKNOWN, NULL, 0,
-        feature_levels, G_N_ELEMENTS (feature_levels),
-        D3D11_SDK_VERSION, &self->d3d11_device, &feature_level,
-        &self->d3d11_context);
-    if (FAILED (hr)) {
-      HR_FAILED_INFO (hr, D3D11CreateDevice);
-      PTR_RELEASE (dxgi_adapter1);
-      continue;
-    }
-
-    for (j = 0; IDXGIAdapter1_EnumOutputs (dxgi_adapter1, j, &dxgi_output) !=
-        DXGI_ERROR_NOT_FOUND; ++j) {
-      DXGI_OUTPUT_DESC output_desc;
-      hr = IDXGIOutput_QueryInterface (dxgi_output, &IID_IDXGIOutput1,
-          (void **) &self->dxgi_output1);
-      PTR_RELEASE (dxgi_output);
-      HR_FAILED_GOTO (hr, IDXGIOutput::QueryInterface, new_error);
-
-      hr = IDXGIOutput1_GetDesc (self->dxgi_output1, &output_desc);
-      HR_FAILED_GOTO (hr, IDXGIOutput1::GetDesc, new_error);
-
-      if (output_desc.Monitor == monitor) {
-        GST_DEBUG_OBJECT (src, "found monitor");
-        break;
-      }
-
-      PTR_RELEASE (self->dxgi_output1);
-    }
-
-    PTR_RELEASE (dxgi_adapter1);
-
-    if (NULL != self->dxgi_output1) {
-      break;
-    }
-
-    PTR_RELEASE (self->d3d11_device);
-    PTR_RELEASE (self->d3d11_context);
-  }
-
-  if (NULL == self->dxgi_output1) {
-    goto new_error;
-  }
-
-  PTR_RELEASE (dxgi_factory1);
-
-  if (initialize_output_duplication (self) == GST_FLOW_ERROR) {
-    goto new_error;
-  }
-
-  self->pointer_buffer_capacity = INITIAL_POINTER_BUFFER_CAPACITY;
-  self->pointer_buffer = g_malloc (self->pointer_buffer_capacity);
-  if (NULL == self->pointer_buffer) {
-    goto new_error;
-  }
-
-  self->move_rects_capacity = INITIAL_MOVE_RECTS_CAPACITY;
-  self->move_rects = g_new0 (DXGI_OUTDUPL_MOVE_RECT, self->move_rects_capacity);
-  if (NULL == self->move_rects) {
-    goto new_error;
-  }
-
-  self->dirty_rects_capacity = INITIAL_DIRTY_RECTS_CAPACITY;
-  self->dirty_rects = g_new0 (RECT, self->dirty_rects_capacity);
-  if (NULL == self->dirty_rects) {
-    goto new_error;
-  }
-
-  self->verteces_capacity = INITIAL_VERTICES_CAPACITY;
-  self->dirty_verteces = g_new0 (vertex, self->verteces_capacity);
-  if (NULL == self->dirty_verteces) {
-    goto new_error;
-  }
-
-  self->copy_rects_capacity = INITIAL_COPY_RECTS_CAPACITY;
-  self->copy_rects = g_new0 (RECT, self->copy_rects_capacity);
-  if (NULL == self->copy_rects) {
-    goto new_error;
-  }
-
-  if (DXGI_MODE_ROTATION_IDENTITY != self->dupl_desc.Rotation) {
-    g_assert (GstD3DCompileFunc);
-
-    /* For a rotated display, create a shader. */
-    hr = GstD3DCompileFunc (STR_VERTEX_SHADER, sizeof (STR_VERTEX_SHADER),
-        NULL, NULL, NULL, "vs_main", "vs_4_0_level_9_1",
-        0, 0, &vertex_shader_blob, NULL);
-    HR_FAILED_GOTO (hr, D3DCompile, new_error);
-
-    hr = GstD3DCompileFunc (STR_PIXEL_SHADER, sizeof (STR_PIXEL_SHADER),
-        NULL, NULL, NULL, "ps_main", "ps_4_0_level_9_1",
-        0, 0, &pixel_shader_blob, NULL);
-    HR_FAILED_GOTO (hr, D3DCompile, new_error);
-
-    hr = ID3D11Device_CreateVertexShader (self->d3d11_device,
-        ID3D10Blob_GetBufferPointer (vertex_shader_blob),
-        ID3D10Blob_GetBufferSize (vertex_shader_blob), NULL,
-        &self->vertex_shader);
-    HR_FAILED_GOTO (hr, ID3D11Device::CreateVertexShader, new_error);
-
-    hr = ID3D11Device_CreateInputLayout (self->d3d11_device, vertex_layout,
-        G_N_ELEMENTS (vertex_layout),
-        ID3D10Blob_GetBufferPointer (vertex_shader_blob),
-        ID3D10Blob_GetBufferSize (vertex_shader_blob), &vertex_input_layout);
-    PTR_RELEASE (vertex_shader_blob)
-        HR_FAILED_GOTO (hr, ID3D11Device::CreateInputLayout, new_error);
-
-    ID3D11DeviceContext_IASetInputLayout (self->d3d11_context,
-        vertex_input_layout);
-    PTR_RELEASE (vertex_input_layout);
-
-    hr = ID3D11Device_CreatePixelShader (self->d3d11_device,
-        ID3D10Blob_GetBufferPointer (pixel_shader_blob),
-        ID3D10Blob_GetBufferSize (pixel_shader_blob), NULL,
-        &self->pixel_shader);
-    PTR_RELEASE (pixel_shader_blob);
-    HR_FAILED_GOTO (hr, ID3D11Device::CreatePixelShader, new_error);
-
-    memset (&sampler_desc, 0, sizeof (sampler_desc));
-    sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
-    sampler_desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
-    sampler_desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
-    sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
-    sampler_desc.ComparisonFunc = D3D11_COMPARISON_NEVER;
-    sampler_desc.MinLOD = 0;
-    sampler_desc.MaxLOD = D3D11_FLOAT32_MAX;
-
-    hr = ID3D11Device_CreateSamplerState (self->d3d11_device, &sampler_desc,
-        &self->sampler_state);
-    HR_FAILED_GOTO (hr, ID3D11Device::CreateSamplerState, new_error);
-  }
-
-  return self;
-
-new_error:
-  PTR_RELEASE (vertex_input_layout);
-  PTR_RELEASE (vertex_shader_blob);
-  PTR_RELEASE (pixel_shader_blob);
-
-  dxgicap_destory (self);
-  return NULL;
-}
-
-void
-dxgicap_destory (DxgiCapture * self)
-{
-  if (!self)
-    return;
-  PTR_RELEASE (self->target_view);
-  PTR_RELEASE (self->readable_texture);
-  PTR_RELEASE (self->work_texture);
-  PTR_RELEASE (self->dxgi_output1);
-  PTR_RELEASE (self->dxgi_dupl);
-  PTR_RELEASE (self->d3d11_context);
-  PTR_RELEASE (self->d3d11_device);
-  PTR_RELEASE (self->vertex_shader);
-  PTR_RELEASE (self->pixel_shader);
-  PTR_RELEASE (self->sampler_state);
-
-  g_free (self->pointer_buffer);
-  g_free (self->move_rects);
-  g_free (self->dirty_rects);
-  g_free (self->dirty_verteces);
-  g_free (self->copy_rects);
-
-  g_free (self);
-}
-
-gboolean
-dxgicap_start (DxgiCapture * self)
-{
-  return _setup_texture (self);
-}
-
-void
-dxgicap_stop (DxgiCapture * self)
-{
-  PTR_RELEASE (self->target_view);
-  PTR_RELEASE (self->readable_texture);
-  PTR_RELEASE (self->work_texture);
-}
-
-GstFlowReturn
-dxgicap_acquire_next_frame (DxgiCapture * self, gboolean show_cursor,
-    guint timeout)
-{
-  GstFlowReturn ret = GST_FLOW_ERROR;
-  HRESULT hr;
-  GstDXGIScreenCapSrc *src = self->src;
-
-  DXGI_OUTDUPL_FRAME_INFO frame_info;
-  IDXGIResource *desktop_resource = NULL;
-
-  if (!self->dxgi_dupl) {
-    /* Desktop duplication interface became invalid due to desktop switch,
-     * UAC prompt popping up, or similar event. Try to reinitialize. */
-    ret = initialize_output_duplication (self);
-    goto end;
-  }
-
-  /* Get the latest desktop frames. */
-  hr = IDXGIOutputDuplication_AcquireNextFrame (self->dxgi_dupl,
-      timeout, &frame_info, &desktop_resource);
-  if (hr == DXGI_ERROR_WAIT_TIMEOUT) {
-    /* In case of DXGI_ERROR_WAIT_TIMEOUT,
-     * it has not changed from the last time. */
-    GST_LOG_OBJECT (src, "DXGI_ERROR_WAIT_TIMEOUT");
-    ret = GST_FLOW_OK;
-    goto end;
-  } else if (hr == DXGI_ERROR_ACCESS_LOST) {
-    GST_LOG_OBJECT (src, "DXGI_ERROR_ACCESS_LOST; reinitializing output "
-        "duplication...");
-    PTR_RELEASE (self->dxgi_dupl);
-    ret = GST_FLOW_OK;
-    goto end;
-  }
-  HR_FAILED_GOTO (hr, IDXGIOutputDuplication::AcquireNextFrame, end);
-
-  if (0 != frame_info.LastPresentTime.QuadPart) {
-    /* The desktop frame has changed since last time. */
-    hr = _update_work_texture (self, desktop_resource);
-    if (FAILED (hr)) {
-      GST_DEBUG_OBJECT (src, "failed to _update_work_texture");
-      goto end;
-    }
-  }
-
-  if (show_cursor && 0 != frame_info.LastMouseUpdateTime.QuadPart) {
-    /* The mouse pointer has changed since last time. */
-    self->last_pointer_position = frame_info.PointerPosition;
-
-    if (0 < frame_info.PointerShapeBufferSize) {
-      /* A valid mouse cursor shape exists. */
-      DXGI_OUTDUPL_POINTER_SHAPE_INFO pointer_shape_info;
-      guint pointer_shape_size_required;
-      /* Get the mouse cursor shape. */
-      hr = IDXGIOutputDuplication_GetFramePointerShape (self->dxgi_dupl,
-          self->pointer_buffer_capacity,
-          self->pointer_buffer,
-          &pointer_shape_size_required, &pointer_shape_info);
-      if (DXGI_ERROR_MORE_DATA == hr) {
-        /* not enough buffers */
-        self->pointer_buffer_capacity = pointer_shape_size_required * 2;
-        self->pointer_buffer =
-            g_realloc (self->pointer_buffer, self->pointer_buffer_capacity);
-
-        hr = IDXGIOutputDuplication_GetFramePointerShape (self->dxgi_dupl,
-            self->pointer_buffer_capacity,
-            self->pointer_buffer,
-            &pointer_shape_size_required, &pointer_shape_info);
-      }
-      HR_FAILED_GOTO (hr, IDXGIOutputDuplication::GetFramePointerShape, end);
-      self->pointer_shape_info = pointer_shape_info;
-      ret = GST_FLOW_OK;
-    } else {
-      ret = GST_FLOW_OK;
-    }
-  } else {
-    ret = GST_FLOW_OK;
-  }
-end:
-  if (self->dxgi_dupl) {
-    IDXGIOutputDuplication_ReleaseFrame (self->dxgi_dupl);
-  }
-  PTR_RELEASE (desktop_resource);
-  return ret;
-}
-
-gboolean
-dxgicap_copy_buffer (DxgiCapture * self, gboolean show_cursor, LPRECT dst_rect,
-    GstVideoInfo * video_info, GstBuffer * buf)
-{
-  HRESULT hr;
-  int i;
-  GstDXGIScreenCapSrc *src = self->src;
-  D3D11_MAPPED_SUBRESOURCE readable_map;
-  GstVideoFrame vframe;
-  gint height = RECT_HEIGHT ((*dst_rect));
-  gint width = RECT_WIDTH ((*dst_rect));
-
-  if (NULL == self->readable_texture) {
-    GST_DEBUG_OBJECT (src, "readable_texture is null");
-    goto flow_error;
-  }
-
-  hr = ID3D11DeviceContext_Map (self->d3d11_context,
-      (ID3D11Resource *) self->readable_texture, 0,
-      D3D11_MAP_READ, 0, &readable_map);
-  HR_FAILED_GOTO (hr, IDXGISurface1::Map, flow_error);
-  GST_DEBUG_OBJECT (src, "copy size width:%d height:%d", width, height);
-
-  /* Copy from readable_texture to GstVideFrame. */
-  if (gst_video_frame_map (&vframe, video_info, buf, GST_MAP_WRITE)) {
-    gint line_size;
-    gint stride_dst;
-    PBYTE frame_buffer;
-    PBYTE p_dst;
-    PBYTE p_src;
-
-    frame_buffer = GST_VIDEO_FRAME_PLANE_DATA (&vframe, 0);
-    p_src = (PBYTE) readable_map.pData +
-        (dst_rect->top * readable_map.RowPitch) +
-        (dst_rect->left * BYTE_PER_PIXEL);
-    p_dst = frame_buffer;
-
-    line_size = width * BYTE_PER_PIXEL;
-    stride_dst = GST_VIDEO_FRAME_PLANE_STRIDE (&vframe, 0);
-
-    if (line_size > stride_dst) {
-      GST_ERROR_OBJECT (src, "not enough stride in video frame");
-      ID3D11DeviceContext_Unmap (self->d3d11_context,
-          (ID3D11Resource *) self->readable_texture, 0);
-      gst_video_frame_unmap (&vframe);
-      goto flow_error;
-    }
-
-    for (i = 0; i < height; ++i) {
-      memcpy (p_dst, p_src, line_size);
-      p_dst += stride_dst;
-      p_src += readable_map.RowPitch;
-    }
-    ID3D11DeviceContext_Unmap (self->d3d11_context,
-        (ID3D11Resource *) self->readable_texture, 0);
-    HR_FAILED_GOTO (hr, IDXGISurface1::Unmap, flow_error);
-
-    if (show_cursor && self->last_pointer_position.Visible) {
-      _draw_pointer (self, frame_buffer, dst_rect, stride_dst);
-    }
-    gst_video_frame_unmap (&vframe);
-    return TRUE;
-  }
-
-flow_error:
-  return FALSE;
-}
-
-static void
-_draw_pointer (DxgiCapture * self, PBYTE buffer, LPRECT dst_rect, int stride)
-{
-  RECT pointer_rect;
-  RECT clip_pointer_rect;
-  int offset_x;
-  int offset_y;
-  PBYTE p_dst;
-  /* For DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MONOCHROME, halve the height. */
-  int pointer_height =
-      (DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MONOCHROME ==
-      self->pointer_shape_info.Type)
-      ? self->pointer_shape_info.Height / 2 : self->pointer_shape_info.Height;
-
-  /* A rectangular area containing the mouse pointer shape */
-  SetRect (&pointer_rect,
-      self->last_pointer_position.Position.x,
-      self->last_pointer_position.Position.y,
-      self->last_pointer_position.Position.x +
-      self->pointer_shape_info.Width,
-      self->last_pointer_position.Position.y + pointer_height);
-
-  if (!IntersectRect (&clip_pointer_rect, dst_rect, &pointer_rect)) {
-    return;
-  }
-
-  /* Draw a pointer if it overlaps the destination rectangle range.
-   * There are three ways to draw the mouse cursor.
-   * see  https://docs.microsoft.com/ja-jp/windows/win32/api/dxgi1_2/ne-dxgi1_2-dxgi_outdupl_pointer_shape_type */
-  offset_x = clip_pointer_rect.left - pointer_rect.left;
-  offset_y = clip_pointer_rect.top - pointer_rect.top;
-  p_dst =
-      ((PBYTE) buffer) + ((clip_pointer_rect.top -
-          dst_rect->top) * stride) +
-      ((clip_pointer_rect.left - dst_rect->left) * BYTE_PER_PIXEL);
-
-  if (DXGI_OUTDUPL_POINTER_SHAPE_TYPE_COLOR ==
-      self->pointer_shape_info.Type
-      || DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MASKED_COLOR ==
-      self->pointer_shape_info.Type) {
-    gboolean mask_mode =
-        DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MASKED_COLOR ==
-        self->pointer_shape_info.Type;
-    PBYTE p_src =
-        (PBYTE) self->pointer_buffer +
-        (offset_y * self->pointer_shape_info.Pitch) +
-        (offset_x * BYTE_PER_PIXEL);
-
-    int y, x;
-    for (y = 0; y < RECT_HEIGHT (clip_pointer_rect); ++y) {
-      for (x = 0; x < RECT_WIDTH (clip_pointer_rect); ++x) {
-        PBYTE p1 = p_dst + (x * BYTE_PER_PIXEL);
-        PBYTE p2 = p_src + (x * BYTE_PER_PIXEL);
-        int alpha = *(p2 + 3);
-        int i;
-        for (i = 0; i < 3; ++i) {
-          if (mask_mode) {
-            /* case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MASKED_COLOR:
-             * If the alpha channel of a pixel in the mouse image is 0, copy it.
-             * Otherwise, xor each pixel. */
-            if (0 == alpha) {
-              *p1 = *p2;
-            } else {
-              *p1 = *p2 ^ *p1;
-            }
-          } else {
-            /* case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_COLOR:
-             * Copies the mouse cursor image with alpha channel composition. */
-            *p1 = min (255, max (0, *p1 + ((*p2 - *p1) * alpha / 255)));
-          }
-          ++p1;
-          ++p2;
-        }
-      }
-      p_dst += stride;
-      p_src += self->pointer_shape_info.Pitch;
-    }
-  } else if (DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MONOCHROME ==
-      self->pointer_shape_info.Type) {
-    guint mask_bit = 0x80;
-    /* AND MASK pointer
-     * It is stored in 1 bit per pixel from the beginning. */
-    PBYTE p_src_and =
-        (PBYTE) self->pointer_buffer +
-        (offset_y * self->pointer_shape_info.Pitch);
-    /* XOR MASK pointer
-     * The XOR MASK is stored after the AND mask. */
-    PBYTE p_src_xor =
-        (PBYTE) self->pointer_buffer +
-        ((offset_y + pointer_height) * self->pointer_shape_info.Pitch);
-
-    int y, x;
-    for (y = 0; y < RECT_HEIGHT (clip_pointer_rect); ++y) {
-      guint32 *p_dst_32 = ((guint32 *) (p_dst));
-      for (x = offset_x; x < RECT_WIDTH (clip_pointer_rect); ++x) {
-        int bit_pos = x % 8;
-        gboolean and_bit =
-            0 != (*(p_src_and + (x / 8)) & (mask_bit >> bit_pos));
-        gboolean xor_bit =
-            0 != (*(p_src_xor + (x / 8)) & (mask_bit >> bit_pos));
-
-        if (and_bit) {
-          if (xor_bit) {
-            *p_dst_32 = *p_dst_32 ^ 0x00ffffff;
-          }
-        } else {
-          if (xor_bit) {
-            *p_dst_32 = 0xffffffff;
-          } else {
-            *p_dst_32 = 0xff000000;
-          }
-        }
-        ++p_dst_32;
-      }
-      p_dst += stride;
-      p_src_and += self->pointer_shape_info.Pitch;
-      p_src_xor += self->pointer_shape_info.Pitch;
-    }
-  }
-}
-
-static ID3D11Texture2D *
-_create_texture (DxgiCapture * self,
-    enum D3D11_USAGE usage, UINT bindFlags, UINT cpuAccessFlags)
-{
-  HRESULT hr;
-  GstDXGIScreenCapSrc *src = self->src;
-  D3D11_TEXTURE2D_DESC new_desc;
-  ID3D11Texture2D *new_texture = NULL;
-
-  ZeroMemory (&new_desc, sizeof (new_desc));
-  new_desc.Width = self->dupl_desc.ModeDesc.Width;
-  new_desc.Height = self->dupl_desc.ModeDesc.Height;
-  new_desc.MipLevels = 1;
-  new_desc.ArraySize = 1;
-  new_desc.SampleDesc.Count = 1;
-  new_desc.SampleDesc.Quality = 0;
-  new_desc.Usage = usage;
-  new_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
-  new_desc.BindFlags = bindFlags;
-  new_desc.CPUAccessFlags = cpuAccessFlags;
-  new_desc.MiscFlags = 0;
-
-  hr = ID3D11Device_CreateTexture2D (self->d3d11_device, &new_desc, NULL,
-      &new_texture);
-  HR_FAILED_RET (hr, ID3D11Device::CreateTexture2D, NULL);
-
-  return new_texture;
-}
-
-static gboolean
-_setup_texture (DxgiCapture * self)
-{
-  HRESULT hr;
-  ID3D11Texture2D *new_texture = NULL;
-  GstDXGIScreenCapSrc *src = self->src;
-
-  if (NULL == self->readable_texture) {
-    new_texture = _create_texture (self, D3D11_USAGE_STAGING, 0,
-        D3D11_CPU_ACCESS_READ);
-    if (NULL == new_texture) {
-      return FALSE;
-    }
-    self->readable_texture = new_texture;
-  }
-
-  if (DXGI_MODE_ROTATION_IDENTITY != self->dupl_desc.Rotation) {
-    /* For rotated displays, create work_texture. */
-    if (NULL == self->work_texture) {
-      new_texture =
-          _create_texture (self, D3D11_USAGE_DEFAULT,
-          D3D11_BIND_RENDER_TARGET, 0);
-      if (NULL == new_texture) {
-        return FALSE;
-      }
-
-      self->work_texture = new_texture;
-      ID3D11Texture2D_GetDesc (self->work_texture, &self->work_texture_desc);
-      hr = ID3D11Device_CreateRenderTargetView (self->d3d11_device,
-          (ID3D11Resource *) self->work_texture, NULL, &self->target_view);
-      HR_FAILED_RET (hr, ID3D11Device::CreateRenderTargetView, FALSE);
-
-      self->view_port.Width = (float) self->work_texture_desc.Width;
-      self->view_port.Height = (float) self->work_texture_desc.Height;
-      self->view_port.MinDepth = 0.0f;
-      self->view_port.MaxDepth = 1.0f;
-      self->view_port.TopLeftX = 0.0f;
-      self->view_port.TopLeftY = 0.0f;
-    }
-  }
-
-  return TRUE;
-}
-
-/* Update work_texture to the latest desktop frame from the update information
- * that can be obtained from IDXGIOutputDuplication.
- * Then copy to readable_texture.
- */
-static HRESULT
-_update_work_texture (DxgiCapture * self, IDXGIResource * desktop_resource)
-{
-  HRESULT hr = S_OK;
-  GstDXGIScreenCapSrc *src = self->src;
-  int i;
-  ID3D11Texture2D *desktop_texture = NULL;
-  guint required_size;
-  guint move_count;
-  guint dirty_rects_capacity_size;
-  guint dirty_count;
-  guint copy_count;
-  D3D11_TEXTURE2D_DESC src_desc;
-  RECT *dst_rect;
-  ID3D11Texture2D *work_src;
-  guint move_rects_capacity_size =
-      sizeof (DXGI_OUTDUPL_MOVE_RECT) * self->move_rects_capacity;
-
-  hr = IDXGIResource_QueryInterface (desktop_resource, &IID_ID3D11Texture2D,
-      (void **) &desktop_texture);
-  HR_FAILED_GOTO (hr, IDXGIResource::QueryInterface, end);
-
-  /* Get the rectangular regions that was moved from the last time.
-   * However, I have never obtained a valid value in GetFrameMoveRects.
-   * It seems to depend on the implementation of the GPU driver.
-   * see https://docs.microsoft.com/en-us/windows/win32/api/dxgi1_2/nf-dxgi1_2-idxgioutputduplication-getframemoverects
-   */
-  hr = IDXGIOutputDuplication_GetFrameMoveRects (self->dxgi_dupl,
-      move_rects_capacity_size, self->move_rects, &required_size);
-  if (DXGI_ERROR_MORE_DATA == hr) {
-    /* not enough buffers */
-    self->move_rects_capacity =
-        (required_size / sizeof (DXGI_OUTDUPL_MOVE_RECT)) * 2;
-    self->move_rects =
-        g_renew (DXGI_OUTDUPL_MOVE_RECT, self->move_rects,
-        self->move_rects_capacity);
-
-    hr = IDXGIOutputDuplication_GetFrameMoveRects (self->dxgi_dupl,
-        required_size, self->move_rects, &required_size);
-  }
-  HR_FAILED_GOTO (hr, IDXGIOutputDuplication::GetFrameMoveRects, end);
-  move_count = required_size / sizeof (DXGI_OUTDUPL_MOVE_RECT);
-
-  dirty_rects_capacity_size = sizeof (RECT) * self->dirty_rects_capacity;
-  /* Gets the rectangular regions that has changed since the last time.
-     see https://docs.microsoft.com/en-us/windows/win32/api/dxgi1_2/nf-dxgi1_2-idxgioutputduplication-getframedirtyrects
-   */
-  hr = IDXGIOutputDuplication_GetFrameDirtyRects (self->dxgi_dupl,
-      dirty_rects_capacity_size, self->dirty_rects, &required_size);
-
-  if (DXGI_ERROR_MORE_DATA == hr) {
-    /* not enough buffers */
-    self->dirty_rects_capacity = (required_size / sizeof (RECT)) * 2;
-    self->dirty_rects =
-        g_renew (RECT, self->dirty_rects, self->dirty_rects_capacity);
-
-    hr = IDXGIOutputDuplication_GetFrameDirtyRects (self->dxgi_dupl,
-        required_size, self->dirty_rects, &required_size);
-  }
-  HR_FAILED_GOTO (hr, IDXGIOutputDuplication::GetFrameDirtyRects, end);
-
-  dirty_count = required_size / sizeof (RECT);
-
-  /* The number of rectangular regions to copy to the readable_texture. */
-  copy_count = move_count + dirty_count;
-
-  if (self->copy_rects_capacity < copy_count) {
-    /* not enough buffers */
-    self->copy_rects_capacity = copy_count * 2;
-    self->copy_rects =
-        g_renew (RECT, self->copy_rects, self->copy_rects_capacity);
-  }
-
-  if (DXGI_MODE_ROTATION_IDENTITY == self->dupl_desc.Rotation) {
-    /* For a non-rotating display, copy it directly into readable_texture. */
-    RECT *p = self->copy_rects;
-    for (i = 0; i < move_count; ++i) {
-      *p = self->move_rects[i].DestinationRect;
-      ++p;
-    }
-    for (i = 0; i < dirty_count; ++i) {
-      *p = self->dirty_rects[i];
-      ++p;
-    }
-    work_src = desktop_texture;
-  } else {
-    /* For rotated displays, rotate to work_texture and copy. */
-    ID3D11Texture2D_GetDesc (desktop_texture, &src_desc);
-    dst_rect = self->copy_rects;
-    /* Copy the dirty rectangular and moved rectangular regions from desktop frame to work_texture. */
-    hr = _copy_dirty_fragment (self, desktop_texture, &src_desc, move_count,
-        dirty_count, &dst_rect);
-    work_src = self->work_texture;
-    if (FAILED (hr)) {
-      goto end;
-    }
-  }
-
-  /* Copy the updated rectangular regions to readable_texture. */
-  for (i = 0; i < copy_count; ++i) {
-    RECT *p = (self->copy_rects + i);
-    D3D11_BOX box;
-    box.left = p->left;
-    box.top = p->top;
-    box.front = 0;
-    box.right = p->right;
-    box.bottom = p->bottom;
-    box.back = 1;
-
-    ID3D11DeviceContext_CopySubresourceRegion (self->d3d11_context,
-        (ID3D11Resource *) self->readable_texture,
-        0, p->left, p->top, 0, (ID3D11Resource *) work_src, 0, &box);
-  }
-
-end:
-  PTR_RELEASE (desktop_texture);
-  return hr;
-}
-
-static void
-_rotate_rect (DXGI_MODE_ROTATION rotation, RECT * dst, const RECT * src,
-    gint dst_width, gint dst_height)
-{
-  switch (rotation) {
-    case DXGI_MODE_ROTATION_ROTATE90:
-      dst->left = dst_width - src->bottom;
-      dst->top = src->left;
-      dst->right = dst_width - src->top;
-      dst->bottom = src->right;
-      break;
-    case DXGI_MODE_ROTATION_ROTATE180:
-      dst->left = dst_width - src->right;
-      dst->top = dst_height - src->bottom;
-      dst->right = dst_width - src->left;
-      dst->bottom = dst_height - src->top;
-      break;
-    case DXGI_MODE_ROTATION_ROTATE270:
-      dst->left = src->top;
-      dst->top = dst_height - src->right;
-      dst->right = src->bottom;
-      dst->bottom = dst_height - src->left;
-      break;
-    default:
-      *dst = *src;
-      break;
-  }
-}
-
-/* Copy the rectangular area specified by dirty_rects and move_rects from src_texture to work_texture. */
-static HRESULT
-_copy_dirty_fragment (DxgiCapture * self, ID3D11Texture2D * src_texture,
-    const D3D11_TEXTURE2D_DESC * src_desc, guint move_count, guint dirty_count,
-    RECT ** dst_rect)
-{
-  HRESULT hr = S_OK;
-  GstDXGIScreenCapSrc *src = self->src;
-  int i;
-  RECT *dst_rect_p;
-  vertex *vp;
-  UINT stride;
-  UINT offset;
-  guint verteces_count;
-  ID3D11Buffer *verteces_buffer = NULL;
-  ID3D11ShaderResourceView *shader_resource = NULL;
-  D3D11_SUBRESOURCE_DATA subresource_data;
-  D3D11_BUFFER_DESC buffer_desc;
-  D3D11_SHADER_RESOURCE_VIEW_DESC shader_desc;
-
-  shader_desc.Format = src_desc->Format;
-  shader_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
-  shader_desc.Texture2D.MostDetailedMip = src_desc->MipLevels - 1;
-  shader_desc.Texture2D.MipLevels = src_desc->MipLevels;
-  hr = ID3D11Device_CreateShaderResourceView (self->d3d11_device,
-      (ID3D11Resource *) src_texture, &shader_desc, &shader_resource);
-  HR_FAILED_GOTO (hr, ID3D11Device::CreateShaderResourceView, end);
-
-  ID3D11DeviceContext_OMSetRenderTargets (self->d3d11_context, 1,
-      &self->target_view, NULL);
-
-  ID3D11DeviceContext_VSSetShader (self->d3d11_context, self->vertex_shader,
-      NULL, 0);
-
-  ID3D11DeviceContext_PSSetShader (self->d3d11_context, self->pixel_shader,
-      NULL, 0);
-
-  ID3D11DeviceContext_PSSetShaderResources (self->d3d11_context, 0, 1,
-      &shader_resource);
-
-  ID3D11DeviceContext_PSSetSamplers (self->d3d11_context, 0, 1,
-      &self->sampler_state);
-
-  ID3D11DeviceContext_IASetPrimitiveTopology (self->d3d11_context,
-      D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
-
-  verteces_count = (move_count + dirty_count) * VERTEX_NUM;
-  if (verteces_count > self->verteces_capacity) {
-    /* not enough buffers */
-    self->verteces_capacity = verteces_count * 2;
-    self->dirty_verteces =
-        g_renew (vertex, self->dirty_verteces, self->verteces_capacity);
-    if (NULL == self->dirty_verteces) {
-      hr = S_FALSE;
-      goto end;
-    }
-  }
-
-  dst_rect_p = *dst_rect;
-  vp = self->dirty_verteces;
-  /* Create a vertex buffer to move and rotate from the move_rects.
-   * And set the rectangular region to be copied to readable_texture. */
-  for (i = 0; i < move_count; ++i) {
-    /* Copy the area to be moved.
-     * The source of the move is included in dirty_rects. */
-    _set_verteces (self, vp, dst_rect_p, &self->work_texture_desc,
-        &(self->move_rects[i].DestinationRect), src_desc);
-    vp += VERTEX_NUM;
-    ++dst_rect_p;
-  }
-  /* Create a vertex buffer to move and rotate from the dirty_rects.
-   * And set the rectangular region to be copied to readable_texture. */
-  for (i = 0; i < dirty_count; ++i) {
-    _set_verteces (self, vp, dst_rect_p, &self->work_texture_desc,
-        &(self->dirty_rects[i]), src_desc);
-    vp += VERTEX_NUM;
-    ++dst_rect_p;
-  }
-  *dst_rect = dst_rect_p;
-
-  memset (&buffer_desc, 0, sizeof (buffer_desc));
-  buffer_desc.Usage = D3D11_USAGE_IMMUTABLE;
-  buffer_desc.ByteWidth = verteces_count * sizeof (vertex);
-  buffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
-  buffer_desc.CPUAccessFlags = 0;
-
-  memset (&subresource_data, 0, sizeof (subresource_data));
-  subresource_data.pSysMem = self->dirty_verteces;
-
-  hr = ID3D11Device_CreateBuffer (self->d3d11_device, &buffer_desc,
-      &subresource_data, &verteces_buffer);
-  HR_FAILED_GOTO (hr, ID3D11Device::CreateBuffer, end);
-
-  stride = sizeof (vertex);
-  offset = 0;
-  ID3D11DeviceContext_IASetVertexBuffers (self->d3d11_context, 0, 1,
-      &verteces_buffer, &stride, &offset);
-
-  ID3D11DeviceContext_RSSetViewports (self->d3d11_context, 1, &self->view_port);
-
-  /* Copy the rectangular region indicated by dirty_rects from the desktop frame to work_texture. */
-  ID3D11DeviceContext_Draw (self->d3d11_context, verteces_count, 0);
-
-end:
-  PTR_RELEASE (verteces_buffer);
-  PTR_RELEASE (shader_resource);
-
-  return hr;
-}
-
-static void
-_set_verteces (DxgiCapture * self, vertex * verteces, RECT * dst_rect,
-    const D3D11_TEXTURE2D_DESC * dst_desc, RECT * rect,
-    const D3D11_TEXTURE2D_DESC * src_desc)
-{
-  int center_x;
-  int center_y;
-
-  /* Rectangular area is moved according to the rotation of the display. */
-  _rotate_rect (self->dupl_desc.Rotation, dst_rect, rect, dst_desc->Width,
-      dst_desc->Height);
-
-  /* Set the vertex buffer from the rotation of the display. */
-  switch (self->dupl_desc.Rotation) {
-    case DXGI_MODE_ROTATION_ROTATE90:
-    verteces[0].texcoord = (vector2d) {
-    (float) rect->right / (float) src_desc->Width,
-          (float) rect->bottom / (float) src_desc->Height};
-      verteces[1].texcoord = (vector2d) {
-      (float) rect->left / (float) src_desc->Width,
-            (float) rect->bottom / (float) src_desc->Height};
-      verteces[2].texcoord = (vector2d) {
-      (float) rect->right / (float) src_desc->Width,
-            (float) rect->top / (float) src_desc->Height};
-      verteces[5].texcoord = (vector2d) {
-      (float) rect->left / (float) src_desc->Width,
-            (float) rect->top / (float) src_desc->Height};
-      break;
-    case DXGI_MODE_ROTATION_ROTATE180:
-    verteces[0].texcoord = (vector2d) {
-    (float) rect->right / (float) src_desc->Width,
-          (float) rect->top / (float) src_desc->Height};
-      verteces[1].texcoord = (vector2d) {
-      (float) rect->right / (float) src_desc->Width,
-            (float) rect->bottom / (float) src_desc->Height};
-      verteces[2].texcoord = (vector2d) {
-      (float) rect->left / (float) src_desc->Width,
-            (float) rect->top / (float) src_desc->Height};
-      verteces[5].texcoord = (vector2d) {
-      (float) rect->left / (float) src_desc->Width,
-            (float) rect->bottom / (float) src_desc->Height};
-      break;
-    case DXGI_MODE_ROTATION_ROTATE270:
-    verteces[0].texcoord = (vector2d) {
-    (float) rect->left / (float) src_desc->Width,
-          (float) rect->top / (float) src_desc->Height};
-      verteces[1].texcoord = (vector2d) {
-      (float) rect->right / (float) src_desc->Width,
-            (float) rect->top / (float) src_desc->Height};
-      verteces[2].texcoord = (vector2d) {
-      (float) rect->left / (float) src_desc->Width,
-            (float) rect->bottom / (float) src_desc->Height};
-      verteces[5].texcoord = (vector2d) {
-      (float) rect->right / (float) src_desc->Width,
-            (float) rect->bottom / (float) src_desc->Height};
-      break;
-    default:
-    verteces[0].texcoord = (vector2d) {
-    (float) rect->left / (float) src_desc->Width,
-          (float) rect->bottom / (float) src_desc->Height};
-      verteces[1].texcoord = (vector2d) {
-      (float) rect->left / (float) src_desc->Width,
-            (float) rect->top / (float) src_desc->Height};
-      verteces[2].texcoord = (vector2d) {
-      (float) rect->right / (float) src_desc->Width,
-            (float) rect->bottom / (float) src_desc->Height};
-      verteces[5].texcoord = (vector2d) {
-      (float) rect->right / (float) src_desc->Width,
-            (float) rect->top / (float) src_desc->Height};
-      break;
-  }
-  verteces[3].texcoord = verteces[2].texcoord;
-  verteces[4].texcoord = verteces[1].texcoord;
-
-  center_x = (int) dst_desc->Width / 2;
-  center_y = (int) dst_desc->Height / 2;
-
-  verteces[0].pos = (vector3d) {
-  (float) (dst_rect->left - center_x) / (float) center_x,
-        (float) (dst_rect->bottom - center_y) / (float) center_y *-1.0f, 0.0f};
-  verteces[1].pos = (vector3d) {
-  (float) (dst_rect->left - center_x) / (float) center_x,
-        (float) (dst_rect->top - center_y) / (float) center_y *-1.0f, 0.0f};
-  verteces[2].pos = (vector3d) {
-  (float) (dst_rect->right - center_x) / (float) center_x,
-        (float) (dst_rect->bottom - center_y) / (float) center_y *-1.0f, 0.0f};
-  verteces[3].pos = verteces[2].pos;
-  verteces[4].pos = verteces[1].pos;
-  verteces[5].pos = (vector3d) {
-  (float) (dst_rect->right - center_x) / (float) center_x,
-        (float) (dst_rect->top - center_y) / (float) center_y *-1.0f, 0.0f};
-}
-
-typedef struct _monitor_param_by_name
-{
-  const gchar *device_name;
-  HMONITOR hmonitor;
-} monitor_param_by_name;
-
-static BOOL CALLBACK
-monitor_enum_proc_by_name (HMONITOR hmonitor, HDC hdc, LPRECT rect,
-    LPARAM lparam)
-{
-  MONITORINFOEXA monitor_info;
-  monitor_param_by_name *param = (monitor_param_by_name *) lparam;
-
-  monitor_info.cbSize = sizeof (monitor_info);
-  if (GetMonitorInfoA (hmonitor, (MONITORINFO *) & monitor_info)) {
-    if (0 == g_strcmp0 (monitor_info.szDevice, param->device_name)) {
-      param->hmonitor = hmonitor;
-      return FALSE;
-    }
-  }
-  return TRUE;
-}
-
-HMONITOR
-get_hmonitor_by_device_name (const gchar * device_name)
-{
-  monitor_param_by_name monitor = { device_name, NULL, };
-  EnumDisplayMonitors (NULL, NULL, monitor_enum_proc_by_name,
-      (LPARAM) & monitor);
-  return monitor.hmonitor;
-}
-
-static BOOL CALLBACK
-monitor_enum_proc_primary (HMONITOR hmonitor, HDC hdc, LPRECT rect,
-    LPARAM lparam)
-{
-  MONITORINFOEXA monitor_info;
-  monitor_param_by_name *param = (monitor_param_by_name *) lparam;
-
-  monitor_info.cbSize = sizeof (monitor_info);
-  if (GetMonitorInfoA (hmonitor, (MONITORINFO *) & monitor_info)) {
-    if (MONITORINFOF_PRIMARY == monitor_info.dwFlags) {
-      param->hmonitor = hmonitor;
-      return FALSE;
-    }
-  }
-  return TRUE;
-}
-
-HMONITOR
-get_hmonitor_primary (void)
-{
-  monitor_param_by_name monitor = { NULL, NULL, };
-  EnumDisplayMonitors (NULL, NULL, monitor_enum_proc_primary,
-      (LPARAM) & monitor);
-  return monitor.hmonitor;
-}
-
-typedef struct _monitor_param_by_index
-{
-  int target;
-  int counter;
-  HMONITOR hmonitor;
-} monitor_param_by_index;
-
-static BOOL CALLBACK
-monitor_enum_proc_by_index (HMONITOR hmonitor, HDC hdc, LPRECT rect,
-    LPARAM lparam)
-{
-  MONITORINFOEXA monitor_info;
-  monitor_param_by_index *param = (monitor_param_by_index *) lparam;
-
-  monitor_info.cbSize = sizeof (monitor_info);
-  if (GetMonitorInfoA (hmonitor, (MONITORINFO *) & monitor_info)) {
-    if (param->target == param->counter) {
-      param->hmonitor = hmonitor;
-      return FALSE;
-    }
-  }
-  ++param->counter;
-  return TRUE;
-}
-
-HMONITOR
-get_hmonitor_by_index (int index)
-{
-  monitor_param_by_index monitor = { index, 0, NULL, };
-  EnumDisplayMonitors (NULL, NULL, monitor_enum_proc_by_index,
-      (LPARAM) & monitor);
-  return monitor.hmonitor;
-}
-
-
-gboolean
-get_monitor_physical_size (HMONITOR hmonitor, LPRECT rect)
-{
-  MONITORINFOEXW monitor_info;
-  DEVMODEW dev_mode;
-
-  monitor_info.cbSize = sizeof (monitor_info);
-  if (!GetMonitorInfoW (hmonitor, (LPMONITORINFO) & monitor_info)) {
-    return FALSE;
-  }
-
-  dev_mode.dmSize = sizeof (dev_mode);
-  dev_mode.dmDriverExtra = sizeof (POINTL);
-  dev_mode.dmFields = DM_POSITION;
-  if (!EnumDisplaySettingsW
-      (monitor_info.szDevice, ENUM_CURRENT_SETTINGS, &dev_mode)) {
-    return FALSE;
-  }
-
-  SetRect (rect, 0, 0, dev_mode.dmPelsWidth, dev_mode.dmPelsHeight);
-  return TRUE;
-}
-
-static const gchar *
-_hresult_to_string_fallback (HRESULT hr)
-{
-  const gchar *s = "unknown error";
-
-  switch (hr) {
-    case DXGI_ERROR_ACCESS_DENIED:
-      s = "DXGI_ERROR_ACCESS_DENIED";
-      break;
-    case DXGI_ERROR_ACCESS_LOST:
-      s = "DXGI_ERROR_ACCESS_LOST";
-      break;
-    case DXGI_ERROR_CANNOT_PROTECT_CONTENT:
-      s = "DXGI_ERROR_CANNOT_PROTECT_CONTENT";
-      break;
-    case DXGI_ERROR_DEVICE_HUNG:
-      s = "DXGI_ERROR_DEVICE_HUNG";
-      break;
-    case DXGI_ERROR_DEVICE_REMOVED:
-      s = "DXGI_ERROR_DEVICE_REMOVED";
-      break;
-    case DXGI_ERROR_DEVICE_RESET:
-      s = "DXGI_ERROR_DEVICE_RESET";
-      break;
-    case DXGI_ERROR_DRIVER_INTERNAL_ERROR:
-      s = "DXGI_ERROR_DRIVER_INTERNAL_ERROR";
-      break;
-    case DXGI_ERROR_FRAME_STATISTICS_DISJOINT:
-      s = "DXGI_ERROR_FRAME_STATISTICS_DISJOINT";
-      break;
-    case DXGI_ERROR_GRAPHICS_VIDPN_SOURCE_IN_USE:
-      s = "DXGI_ERROR_GRAPHICS_VIDPN_SOURCE_IN_USE";
-      break;
-    case DXGI_ERROR_INVALID_CALL:
-      s = "DXGI_ERROR_INVALID_CALL";
-      break;
-    case DXGI_ERROR_MORE_DATA:
-      s = "DXGI_ERROR_MORE_DATA";
-      break;
-    case DXGI_ERROR_NAME_ALREADY_EXISTS:
-      s = "DXGI_ERROR_NAME_ALREADY_EXISTS";
-      break;
-    case DXGI_ERROR_NONEXCLUSIVE:
-      s = "DXGI_ERROR_NONEXCLUSIVE";
-      break;
-    case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE:
-      s = "DXGI_ERROR_NOT_CURRENTLY_AVAILABLE";
-      break;
-    case DXGI_ERROR_NOT_FOUND:
-      s = "DXGI_ERROR_NOT_FOUND";
-      break;
-    case DXGI_ERROR_REMOTE_CLIENT_DISCONNECTED:
-      s = "DXGI_ERROR_REMOTE_CLIENT_DISCONNECTED";
-      break;
-    case DXGI_ERROR_REMOTE_OUTOFMEMORY:
-      s = "DXGI_ERROR_REMOTE_OUTOFMEMORY";
-      break;
-    case DXGI_ERROR_RESTRICT_TO_OUTPUT_STALE:
-      s = "DXGI_ERROR_RESTRICT_TO_OUTPUT_STALE";
-      break;
-    case DXGI_ERROR_SDK_COMPONENT_MISSING:
-      s = "DXGI_ERROR_SDK_COMPONENT_MISSING";
-      break;
-    case DXGI_ERROR_SESSION_DISCONNECTED:
-      s = "DXGI_ERROR_SESSION_DISCONNECTED";
-      break;
-    case DXGI_ERROR_UNSUPPORTED:
-      s = "DXGI_ERROR_UNSUPPORTED";
-      break;
-    case DXGI_ERROR_WAIT_TIMEOUT:
-      s = "DXGI_ERROR_WAIT_TIMEOUT";
-      break;
-    case DXGI_ERROR_WAS_STILL_DRAWING:
-      s = "DXGI_ERROR_WAS_STILL_DRAWING";
-      break;
-    case E_FAIL:
-      s = "E_FAIL";
-      break;
-    case E_OUTOFMEMORY:
-      s = "E_OUTOFMEMORY";
-      break;
-    case E_NOTIMPL:
-      s = "E_NOTIMPL";
-      break;
-    case E_ACCESSDENIED:
-      s = "E_ACCESSDENIED";
-      break;
-    case E_POINTER:
-      s = "E_POINTER";
-      break;
-    case E_INVALIDARG:
-      s = "E_INVALIDARG";
-      break;
-#if defined(_MSC_VER) && (_MSC_VER >= 1800)
-    case DXGI_ERROR_ALREADY_EXISTS:
-      s = "DXGI_ERROR_ALREADY_EXISTS";
-      break;
-    case D3D11_ERROR_FILE_NOT_FOUND:
-      s = "D3D11_ERROR_FILE_NOT_FOUND";
-      break;
-    case D3D11_ERROR_TOO_MANY_UNIQUE_STATE_OBJECTS:
-      s = "D3D11_ERROR_TOO_MANY_UNIQUE_STATE_OBJECTS";
-      break;
-    case D3D11_ERROR_TOO_MANY_UNIQUE_VIEW_OBJECTS:
-      s = "D3D11_ERROR_TOO_MANY_UNIQUE_VIEW_OBJECTS";
-      break;
-    case D3D11_ERROR_DEFERRED_CONTEXT_MAP_WITHOUT_INITIAL_DISCARD:
-      s = "D3D11_ERROR_DEFERRED_CONTEXT_MAP_WITHOUT_INITIAL_DISCARD";
-      break;
-#endif
-  }
-  return s;
-}
-
-gchar *
-get_hresult_to_string (HRESULT hr)
-{
-  gchar *error_text = NULL;
-
-  error_text = g_win32_error_message ((gint) hr);
-  /* g_win32_error_message() doesn't cover all HERESULT return code,
-   * so it could be empty string, or null if there was an error
-   * in g_utf16_to_utf8() */
-  if (!error_text || strlen (error_text) == 0) {
-    g_free (error_text);
-    error_text = g_strdup (_hresult_to_string_fallback (hr));
-  }
-
-  return error_text;
-}
diff --git a/subprojects/gst-plugins-bad/sys/winscreencap/dxgicapture.h b/subprojects/gst-plugins-bad/sys/winscreencap/dxgicapture.h
deleted file mode 100644 (file)
index 7d2ad03..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/* GStreamer
- * Copyright (C) 2019 OKADA Jun-ichi <okada@abt.jp>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef __DXGICAP_H__
-#define __DXGICAP_H__
-
-#define COBJMACROS
-#include <d3d11.h>
-#include <dxgi.h>
-#include <dxgi1_2.h>
-#undef COBJMACROS
-
-#include <gst/gst.h>
-#include <gst/base/gstpushsrc.h>
-#include <gst/video/video.h>
-
-#define RECT_WIDTH(r) (r.right - r.left)
-#define RECT_HEIGHT(r) (r.bottom - r.top)
-
-#define HR_FAILED_AND(hr,func,and) \
-  G_STMT_START { \
-    if (FAILED (hr)) { \
-      gchar *msg = get_hresult_to_string (hr); \
-      GST_ERROR_OBJECT (src, #func " failed (%x): %s", (guint) hr, msg); \
-      g_free (msg); \
-      and; \
-    } \
-  } G_STMT_END
-
-#define HR_FAILED_RET(hr,func,ret) HR_FAILED_AND(hr,func,return ret)
-
-#define HR_FAILED_GOTO(hr,func,where) HR_FAILED_AND(hr,func,goto where)
-
-#define HR_FAILED_INFO(hr, func) \
-  G_STMT_START { \
-    if (FAILED (hr)) { \
-      gchar *msg = get_hresult_to_string (hr); \
-      GST_INFO_OBJECT (src, #func " failed (%x): %s", (guint) hr, msg); \
-      g_free (msg); \
-    } \
-  } G_STMT_END
-
-#define GST_DXGICAP_FLOW_RESOLUTION_CHANGE GST_FLOW_CUSTOM_SUCCESS_1
-
-typedef struct _GstDXGIScreenCapSrc GstDXGIScreenCapSrc;
-
-typedef struct _DxgiCapture DxgiCapture;
-
-gboolean gst_dxgicap_shader_init (void);
-
-DxgiCapture *dxgicap_new (HMONITOR monitor, GstDXGIScreenCapSrc * src);
-void dxgicap_destory (DxgiCapture * _this);
-
-gboolean dxgicap_start (DxgiCapture * _this);
-void dxgicap_stop (DxgiCapture * _this);
-
-GstFlowReturn dxgicap_acquire_next_frame (DxgiCapture * _this, gboolean show_cursor,
-    guint timeout);
-gboolean dxgicap_copy_buffer (DxgiCapture * _this, gboolean show_cursor,
-    LPRECT src_rect, GstVideoInfo * video_info, GstBuffer * buf);
-
-HMONITOR get_hmonitor_by_device_name (const gchar * device_name);
-HMONITOR get_hmonitor_primary (void);
-HMONITOR get_hmonitor_by_index (int index);
-
-gboolean get_monitor_physical_size (HMONITOR hmonitor, LPRECT rect);
-
-gchar *get_hresult_to_string (HRESULT hr);
-
-#endif /* __DXGICAP_H__ */
diff --git a/subprojects/gst-plugins-bad/sys/winscreencap/gstdxgiscreencapsrc.c b/subprojects/gst-plugins-bad/sys/winscreencap/gstdxgiscreencapsrc.c
deleted file mode 100644 (file)
index 12c7980..0000000
+++ /dev/null
@@ -1,611 +0,0 @@
-/* GStreamer
- * Copyright (C) 2019 OKADA Jun-ichi <okada@abt.jp>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-/**
- * SECTION:element-dxgiscreencapsrc
- * @title: dxgiscreencapsrc
- *
- * This element uses DXGI Desktop Duplication API.
- * The default is capturing the whole desktop, but #GstDXGIScreenCapSrc:x,
- * #GstDXGIScreenCapSrc:y, #GstDXGIScreenCapSrc:width and
- * #GstDXGIScreenCapSrc:height can be used to select a particular region.
- * Use #GstDXGIScreenCapSrc:monitor for changing which monitor to capture
- * from.
- *
- * ## Example pipelines
- * |[
- * gst-launch-1.0 dxgiscreencapsrc ! videoconvert ! dshowvideosink
- * ]| Capture the desktop and display it.
- * |[
- * gst-launch-1.0 dxgiscreencapsrc x=100 y=100 width=320 height=240 !
- * videoconvert ! dshowvideosink
- * ]| Capture a portion of the desktop and display it.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <windows.h>
-#include <versionhelpers.h>
-#include <gst/video/video.h>
-#include "gstdxgiscreencapsrc.h"
-#include "dxgicapture.h"
-
-GST_DEBUG_CATEGORY_EXTERN (gst_dxgi_screen_cap_src_debug);
-#define GST_CAT_DEFAULT gst_dxgi_screen_cap_src_debug
-
-struct _GstDXGIScreenCapSrc
-{
-  /* Parent */
-  GstPushSrc src;
-
-  /* Properties */
-  gint capture_x;
-  gint capture_y;
-  gint capture_w;
-  gint capture_h;
-  guint monitor;
-  gchar *device_name;
-  gboolean show_cursor;
-
-  /* Source pad frame rate */
-  gint rate_numerator;
-  gint rate_denominator;
-
-  /* Runtime variables */
-  RECT screen_rect;
-  RECT src_rect;
-  guint64 frame_number;
-  GstClockID clock_id;
-  GstVideoInfo video_info;
-
-  /*DXGI capture */
-  DxgiCapture *dxgi_capture;
-};
-
-static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
-    GST_PAD_SRC,
-    GST_PAD_ALWAYS,
-    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("BGRA")));
-
-#define gst_dxgi_screen_cap_src_parent_class parent_class
-G_DEFINE_TYPE (GstDXGIScreenCapSrc, gst_dxgi_screen_cap_src, GST_TYPE_PUSH_SRC);
-
-#define DEFAULT_MONITOR (-1)
-#define DEFAULT_DEVICE_NAME (NULL)
-#define DEFAULT_SHOW_CURSOR (FALSE)
-#define DEFAULT_X_POS (0)
-#define DEFAULT_Y_POS (0)
-#define DEFAULT_WIDTH (0)
-#define DEFAULT_HEIGHT (0)
-
-enum
-{
-  PROP_0,
-  PROP_MONITOR,
-  PROP_DEVICE_NAME,
-  PROP_SHOW_CURSOR,
-  PROP_X_POS,
-  PROP_Y_POS,
-  PROP_WIDTH,
-  PROP_HEIGHT
-};
-
-static void gst_dxgi_screen_cap_src_dispose (GObject * object);
-static void gst_dxgi_screen_cap_src_set_property (GObject * object,
-    guint prop_id, const GValue * value, GParamSpec * pspec);
-static void gst_dxgi_screen_cap_src_get_property (GObject * object,
-    guint prop_id, GValue * value, GParamSpec * pspec);
-
-static GstCaps *gst_dxgi_screen_cap_src_fixate (GstBaseSrc * bsrc,
-    GstCaps * caps);
-static gboolean gst_dxgi_screen_cap_src_set_caps (GstBaseSrc * bsrc,
-    GstCaps * caps);
-static GstCaps *gst_dxgi_screen_cap_src_get_caps (GstBaseSrc * bsrc,
-    GstCaps * filter);
-static gboolean gst_dxgi_screen_cap_src_start (GstBaseSrc * bsrc);
-static gboolean gst_dxgi_screen_cap_src_stop (GstBaseSrc * bsrc);
-
-static gboolean gst_dxgi_screen_cap_src_unlock (GstBaseSrc * bsrc);
-
-static GstFlowReturn gst_dxgi_screen_cap_src_create (GstBaseSrc * pushsrc,
-    guint64 offset, guint length, GstBuffer ** buffer);
-
-static HMONITOR _get_hmonitor (GstDXGIScreenCapSrc * src);
-
-/* Implementation. */
-static void
-gst_dxgi_screen_cap_src_class_init (GstDXGIScreenCapSrcClass * klass)
-{
-  GObjectClass *go_class;
-  GstElementClass *e_class;
-  GstBaseSrcClass *bs_class;
-
-  go_class = G_OBJECT_CLASS (klass);
-  e_class = GST_ELEMENT_CLASS (klass);
-  bs_class = GST_BASE_SRC_CLASS (klass);
-
-  go_class->set_property = gst_dxgi_screen_cap_src_set_property;
-  go_class->get_property = gst_dxgi_screen_cap_src_get_property;
-
-  go_class->dispose = GST_DEBUG_FUNCPTR (gst_dxgi_screen_cap_src_dispose);
-  bs_class->get_caps = GST_DEBUG_FUNCPTR (gst_dxgi_screen_cap_src_get_caps);
-  bs_class->set_caps = GST_DEBUG_FUNCPTR (gst_dxgi_screen_cap_src_set_caps);
-  bs_class->start = GST_DEBUG_FUNCPTR (gst_dxgi_screen_cap_src_start);
-  bs_class->stop = GST_DEBUG_FUNCPTR (gst_dxgi_screen_cap_src_stop);
-  bs_class->unlock = GST_DEBUG_FUNCPTR (gst_dxgi_screen_cap_src_unlock);
-  bs_class->fixate = GST_DEBUG_FUNCPTR (gst_dxgi_screen_cap_src_fixate);
-  bs_class->create = GST_DEBUG_FUNCPTR (gst_dxgi_screen_cap_src_create);
-
-  g_object_class_install_property (go_class, PROP_MONITOR,
-      g_param_spec_int ("monitor", "Monitor",
-          "Which monitor to use (-1 = primary monitor and default)",
-          DEFAULT_MONITOR, G_MAXINT, DEFAULT_MONITOR, G_PARAM_READWRITE));
-  g_object_class_install_property (go_class, PROP_DEVICE_NAME,
-      g_param_spec_string ("device-name", "Monitor device name",
-          "Which monitor to use by device name (e.g. \"\\\\\\\\.\\\\DISPLAY1\")",
-          DEFAULT_DEVICE_NAME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (go_class, PROP_SHOW_CURSOR,
-      g_param_spec_boolean ("cursor",
-          "Show mouse cursor",
-          "Whether to show mouse cursor (default off)",
-          DEFAULT_SHOW_CURSOR, G_PARAM_READWRITE));
-  g_object_class_install_property (go_class, PROP_X_POS,
-      g_param_spec_int ("x", "X",
-          "Horizontal coordinate of top left corner for the screen capture "
-          "area", 0, G_MAXINT, DEFAULT_X_POS, G_PARAM_READWRITE));
-  g_object_class_install_property (go_class, PROP_Y_POS,
-      g_param_spec_int ("y", "Y",
-          "Vertical coordinate of top left corner for the screen capture "
-          "area", 0, G_MAXINT, DEFAULT_Y_POS, G_PARAM_READWRITE));
-  g_object_class_install_property (go_class, PROP_WIDTH,
-      g_param_spec_int ("width", "Width",
-          "Width of screen capture area (0 = maximum)",
-          0, G_MAXINT, DEFAULT_WIDTH, G_PARAM_READWRITE));
-  g_object_class_install_property (go_class, PROP_HEIGHT,
-      g_param_spec_int ("height", "Height",
-          "Height of screen capture area (0 = maximum)",
-          0, G_MAXINT, DEFAULT_HEIGHT, G_PARAM_READWRITE));
-
-  gst_element_class_add_static_pad_template (e_class, &src_template);
-
-  gst_element_class_set_static_metadata (e_class,
-      "DirectX DXGI screen capture source",
-      "Source/Video", "Captures screen", "OKADA Jun-ichi <okada@abt.jp>");
-}
-
-static void
-gst_dxgi_screen_cap_src_init (GstDXGIScreenCapSrc * src)
-{
-  /* Set src element inital values... */
-  src->capture_x = DEFAULT_X_POS;
-  src->capture_y = DEFAULT_Y_POS;
-  src->capture_w = DEFAULT_WIDTH;
-  src->capture_h = DEFAULT_HEIGHT;
-
-  src->monitor = DEFAULT_MONITOR;
-  src->device_name = DEFAULT_DEVICE_NAME;
-  src->show_cursor = DEFAULT_SHOW_CURSOR;
-
-  src->dxgi_capture = NULL;
-
-  gst_base_src_set_live (GST_BASE_SRC (src), TRUE);
-  gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME);
-}
-
-static void
-gst_dxgi_screen_cap_src_dispose (GObject * object)
-{
-  GstDXGIScreenCapSrc *src = GST_DXGI_SCREEN_CAP_SRC (object);
-
-  g_free (src->device_name);
-  src->device_name = NULL;
-
-  dxgicap_destory (src->dxgi_capture);
-  src->dxgi_capture = NULL;
-
-  G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-static void
-gst_dxgi_screen_cap_src_set_property (GObject * object,
-    guint prop_id, const GValue * value, GParamSpec * pspec)
-{
-  GstDXGIScreenCapSrc *src = GST_DXGI_SCREEN_CAP_SRC (object);
-
-  switch (prop_id) {
-    case PROP_MONITOR:
-      src->monitor = g_value_get_int (value);
-      break;
-    case PROP_DEVICE_NAME:
-      g_free (src->device_name);
-      src->device_name = g_value_dup_string (value);
-      break;
-    case PROP_SHOW_CURSOR:
-      src->show_cursor = g_value_get_boolean (value);
-      break;
-    case PROP_X_POS:
-      src->capture_x = g_value_get_int (value);
-      break;
-    case PROP_Y_POS:
-      src->capture_y = g_value_get_int (value);
-      break;
-    case PROP_WIDTH:
-      src->capture_w = g_value_get_int (value);
-      break;
-    case PROP_HEIGHT:
-      src->capture_h = g_value_get_int (value);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  };
-}
-
-static void
-gst_dxgi_screen_cap_src_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec)
-{
-  GstDXGIScreenCapSrc *src = GST_DXGI_SCREEN_CAP_SRC (object);
-
-  switch (prop_id) {
-    case PROP_MONITOR:
-      g_value_set_int (value, src->monitor);
-      break;
-    case PROP_DEVICE_NAME:
-      g_value_set_string (value, src->device_name);
-      break;
-    case PROP_SHOW_CURSOR:
-      g_value_set_boolean (value, src->show_cursor);
-      break;
-    case PROP_X_POS:
-      g_value_set_int (value, src->capture_x);
-      break;
-    case PROP_Y_POS:
-      g_value_set_int (value, src->capture_y);
-      break;
-    case PROP_WIDTH:
-      g_value_set_int (value, src->capture_w);
-      break;
-    case PROP_HEIGHT:
-      g_value_set_int (value, src->capture_h);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  };
-}
-
-static GstCaps *
-gst_dxgi_screen_cap_src_fixate (GstBaseSrc * bsrc, GstCaps * caps)
-{
-  GstStructure *structure;
-
-  caps = gst_caps_make_writable (caps);
-
-  structure = gst_caps_get_structure (caps, 0);
-
-  gst_structure_fixate_field_nearest_int (structure, "width", 640);
-  gst_structure_fixate_field_nearest_int (structure, "height", 480);
-  gst_structure_fixate_field_nearest_fraction (structure, "framerate", 30, 1);
-
-  caps = GST_BASE_SRC_CLASS (parent_class)->fixate (bsrc, caps);
-
-  return caps;
-}
-
-static gboolean
-gst_dxgi_screen_cap_src_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
-{
-  GstDXGIScreenCapSrc *src = GST_DXGI_SCREEN_CAP_SRC (bsrc);
-  GstStructure *structure;
-
-  structure = gst_caps_get_structure (caps, 0);
-
-  src->src_rect = src->screen_rect;
-  if (src->capture_w && src->capture_h) {
-    src->src_rect.left += src->capture_x;
-    src->src_rect.top += src->capture_y;
-    src->src_rect.right = src->src_rect.left + src->capture_w;
-    src->src_rect.bottom = src->src_rect.top + src->capture_h;
-  }
-
-  gst_structure_get_fraction (structure, "framerate",
-      &src->rate_numerator, &src->rate_denominator);
-
-  GST_DEBUG_OBJECT (src, "set_caps size %dx%d, %d/%d fps",
-      (gint) RECT_WIDTH (src->src_rect),
-      (gint) RECT_HEIGHT (src->src_rect),
-      src->rate_numerator, src->rate_denominator);
-
-  gst_video_info_from_caps (&src->video_info, caps);
-  gst_base_src_set_blocksize (bsrc, GST_VIDEO_INFO_SIZE (&src->video_info));
-  return TRUE;
-}
-
-static GstCaps *
-gst_dxgi_screen_cap_src_get_caps (GstBaseSrc * bsrc, GstCaps * filter)
-{
-  GstDXGIScreenCapSrc *src = GST_DXGI_SCREEN_CAP_SRC (bsrc);
-  RECT rect_dst;
-  GstCaps *caps = NULL;
-
-  HMONITOR hmonitor = _get_hmonitor (src);
-  if (!get_monitor_physical_size (hmonitor, &rect_dst)) {
-    GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND,
-        ("Specified monitor with index %d not found", src->monitor), (NULL));
-    return NULL;
-  }
-
-  src->screen_rect = rect_dst;
-  if (src->capture_w && src->capture_h &&
-      src->capture_x + src->capture_w <= RECT_WIDTH (rect_dst) &&
-      src->capture_y + src->capture_h <= RECT_HEIGHT (rect_dst)) {
-    rect_dst.left = src->capture_x;
-    rect_dst.top = src->capture_y;
-    rect_dst.right = src->capture_x + src->capture_w;
-    rect_dst.bottom = src->capture_y + src->capture_h;
-  } else {
-    /* Default values */
-    src->capture_x = src->capture_y = 0;
-    src->capture_w = src->capture_h = 0;
-  }
-
-  /* The desktop image is always in the DXGI_FORMAT_B8G8R8A8_UNORM format. */
-  GST_DEBUG_OBJECT (src, "get_cap rect: %ld, %ld, %ld, %ld", rect_dst.left,
-      rect_dst.top, rect_dst.right, rect_dst.bottom);
-
-  caps =
-      gst_caps_new_simple ("video/x-raw", "format", G_TYPE_STRING, "BGRA",
-      "width", G_TYPE_INT, RECT_WIDTH (rect_dst),
-      "height", G_TYPE_INT, RECT_HEIGHT (rect_dst),
-      "framerate", GST_TYPE_FRACTION_RANGE, 1, 1, G_MAXINT,
-      1, "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1, NULL);
-
-  if (filter) {
-    GstCaps *tmp =
-        gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
-    gst_caps_unref (caps);
-    caps = tmp;
-  }
-  return caps;
-}
-
-static gboolean
-gst_dxgi_screen_cap_src_start (GstBaseSrc * bsrc)
-{
-  GstDXGIScreenCapSrc *src = GST_DXGI_SCREEN_CAP_SRC (bsrc);
-  HMONITOR hmonitor = _get_hmonitor (src);
-  if (NULL == hmonitor) {
-    GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND,
-        ("Specified monitor with index %d not found", src->monitor), (NULL));
-    return FALSE;
-  }
-  src->dxgi_capture = dxgicap_new (hmonitor, src);
-
-  if (NULL == src->dxgi_capture) {
-    GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND,
-        ("Specified monitor with index %d not found", src->monitor), (NULL));
-    return FALSE;
-  }
-  dxgicap_start (src->dxgi_capture);
-
-  src->frame_number = -1;
-  return TRUE;
-}
-
-static gboolean
-gst_dxgi_screen_cap_src_stop (GstBaseSrc * bsrc)
-{
-  GstDXGIScreenCapSrc *src = GST_DXGI_SCREEN_CAP_SRC (bsrc);
-  dxgicap_stop (src->dxgi_capture);
-  dxgicap_destory (src->dxgi_capture);
-  src->dxgi_capture = NULL;
-
-  return TRUE;
-}
-
-static gboolean
-gst_dxgi_screen_cap_src_unlock (GstBaseSrc * bsrc)
-{
-  GstDXGIScreenCapSrc *src = GST_DXGI_SCREEN_CAP_SRC (bsrc);
-
-  GST_OBJECT_LOCK (src);
-  if (src->clock_id) {
-    GST_DEBUG_OBJECT (src, "Waking up waiting clock");
-    gst_clock_id_unschedule (src->clock_id);
-  }
-  GST_OBJECT_UNLOCK (src);
-
-  return TRUE;
-}
-
-static GstFlowReturn
-gst_dxgi_screen_cap_src_create (GstBaseSrc * base_src, guint64 offset,
-    guint length, GstBuffer ** buf)
-{
-  GstDXGIScreenCapSrc *src = GST_DXGI_SCREEN_CAP_SRC (base_src);
-  GstClock *clock;
-  GstClockTime buf_time, buf_dur;
-  guint64 frame_number;
-  GstFlowReturn ret;
-  GstBuffer *buffer = NULL;
-
-  if (G_UNLIKELY (!src->dxgi_capture)) {
-    GST_DEBUG_OBJECT (src, "format wasn't negotiated before create function");
-    return GST_FLOW_NOT_NEGOTIATED;
-  }
-
-  clock = gst_element_get_clock (GST_ELEMENT (src));
-  if (clock != NULL) {
-    GstClockTime time, base_time;
-
-    /* Calculate sync time. */
-
-    time = gst_clock_get_time (clock);
-    base_time = gst_element_get_base_time (GST_ELEMENT (src));
-    buf_time = time - base_time;
-
-    if (src->rate_numerator) {
-      frame_number = gst_util_uint64_scale (buf_time,
-          src->rate_numerator, GST_SECOND * src->rate_denominator);
-    } else {
-      frame_number = -1;
-    }
-  } else {
-    buf_time = GST_CLOCK_TIME_NONE;
-    frame_number = -1;
-  }
-
-  if (frame_number != -1 && frame_number == src->frame_number) {
-    GstClockID id;
-    GstClockReturn ret;
-
-    /* Need to wait for the next frame */
-    frame_number += 1;
-
-    /* Figure out what the next frame time is */
-    buf_time = gst_util_uint64_scale (frame_number,
-        src->rate_denominator * GST_SECOND, src->rate_numerator);
-
-    id = gst_clock_new_single_shot_id (clock,
-        buf_time + gst_element_get_base_time (GST_ELEMENT (src)));
-    GST_OBJECT_LOCK (src);
-    src->clock_id = id;
-    GST_OBJECT_UNLOCK (src);
-
-    GST_DEBUG_OBJECT (src, "Waiting for next frame time %" G_GUINT64_FORMAT,
-        buf_time);
-    ret = gst_clock_id_wait (id, NULL);
-
-    GST_OBJECT_LOCK (src);
-    gst_clock_id_unref (id);
-    src->clock_id = NULL;
-    GST_OBJECT_UNLOCK (src);
-
-    if (ret == GST_CLOCK_UNSCHEDULED) {
-      /* Got woken up by the unlock function */
-      if (clock) {
-        gst_object_unref (clock);
-      }
-      return GST_FLOW_FLUSHING;
-    }
-
-    /* Duration is a complete 1/fps frame duration */
-    buf_dur =
-        gst_util_uint64_scale_int (GST_SECOND, src->rate_denominator,
-        src->rate_numerator);
-  } else if (frame_number != -1) {
-    GstClockTime next_buf_time;
-
-    GST_DEBUG_OBJECT (src, "No need to wait for next frame time %"
-        G_GUINT64_FORMAT " next frame = %" G_GINT64_FORMAT
-        " prev = %" G_GINT64_FORMAT, buf_time, frame_number, src->frame_number);
-    next_buf_time =
-        gst_util_uint64_scale (frame_number + 1,
-        src->rate_denominator * GST_SECOND, src->rate_numerator);
-    /* Frame duration is from now until the next expected capture time */
-    buf_dur = next_buf_time - buf_time;
-  } else {
-    buf_dur = GST_CLOCK_TIME_NONE;
-  }
-  src->frame_number = frame_number;
-
-  if (clock) {
-    gst_object_unref (clock);
-  }
-
-  /* Get the latest desktop frame. */
-  do {
-    ret = dxgicap_acquire_next_frame (src->dxgi_capture, src->show_cursor, 0);
-    if (ret == GST_DXGICAP_FLOW_RESOLUTION_CHANGE) {
-      GST_DEBUG_OBJECT (src, "Resolution change detected.");
-
-      if (!gst_base_src_negotiate (GST_BASE_SRC (src))) {
-        return GST_FLOW_NOT_NEGOTIATED;
-      }
-    }
-  } while (ret == GST_DXGICAP_FLOW_RESOLUTION_CHANGE);
-
-  if (ret != GST_FLOW_OK) {
-    return ret;
-  }
-
-  ret =
-      GST_BASE_SRC_CLASS (g_type_class_peek_parent (parent_class))->alloc
-      (base_src, offset, length, &buffer);
-  if (ret != GST_FLOW_OK) {
-    return ret;
-  }
-
-  /* Copy the latest desktop frame to the video frame. */
-  if (dxgicap_copy_buffer (src->dxgi_capture, src->show_cursor,
-          &src->src_rect, &src->video_info, buffer)) {
-    GST_BUFFER_TIMESTAMP (buffer) = buf_time;
-    GST_BUFFER_DURATION (buffer) = buf_dur;
-    *buf = buffer;
-
-    return GST_FLOW_OK;
-  }
-
-  gst_clear_buffer (&buffer);
-
-  return GST_FLOW_ERROR;
-}
-
-static HMONITOR
-_get_hmonitor (GstDXGIScreenCapSrc * src)
-{
-  HMONITOR hmonitor = NULL;
-  GST_DEBUG_OBJECT (src, "device_name:%s", GST_STR_NULL (src->device_name));
-  if (NULL != src->device_name) {
-    hmonitor = get_hmonitor_by_device_name (src->device_name);
-  }
-  if (NULL == hmonitor && DEFAULT_MONITOR != src->monitor) {
-    hmonitor = get_hmonitor_by_index (src->monitor);
-  }
-  if (NULL == hmonitor) {
-    hmonitor = get_hmonitor_primary ();
-  }
-  return hmonitor;
-}
-
-void
-gst_dxgi_screen_cap_src_register (GstPlugin * plugin, GstRank rank)
-{
-  if (!IsWindows8OrGreater ()) {
-    GST_WARNING ("OS version is too old");
-    return;
-  }
-
-  if (!gst_dxgicap_shader_init ()) {
-    GST_WARNING ("Couldn't load HLS compiler");
-    return;
-  }
-
-  /**
-   * element-dxgiscreencapsrc:
-   *
-   * Since: 1.18
-   */
-  gst_element_register (plugin, "dxgiscreencapsrc",
-      rank, GST_TYPE_DXGI_SCREEN_CAP_SRC);
-}
diff --git a/subprojects/gst-plugins-bad/sys/winscreencap/gstdxgiscreencapsrc.h b/subprojects/gst-plugins-bad/sys/winscreencap/gstdxgiscreencapsrc.h
deleted file mode 100644 (file)
index 4c08c50..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/* GStreamer
- * Copyright (C) 2019 OKADA Jun-ichi <okada@abt.jp>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-#ifndef __GST_DXGI_SCREEN_CAP_SRC_H__
-#define __GST_DXGI_SCREEN_CAP_SRC_H__
-
-#include <windows.h>
-#include <gst/gst.h>
-#include <gst/base/gstpushsrc.h>
-
-G_BEGIN_DECLS
-#define GST_TYPE_DXGI_SCREEN_CAP_SRC  (gst_dxgi_screen_cap_src_get_type())
-G_DECLARE_FINAL_TYPE (GstDXGIScreenCapSrc, gst_dxgi_screen_cap_src, GST,
-    DXGI_SCREEN_CAP_SRC, GstPushSrc);
-
-void gst_dxgi_screen_cap_src_register (GstPlugin * plugin,
-                                       GstRank rank);
-
-G_END_DECLS
-#endif /* __GST_DXGI_SCREEN_CAP_SRC_H__ */
index d62ffff..2dd7150 100644 (file)
 #include "gstgdiscreencapsrc.h"
 #include "gstdx9screencapsrc.h"
 
-#ifdef HAVE_DXGI_CAP
-#include "gstdxgiscreencapsrc.h"
-
-GST_DEBUG_CATEGORY (gst_dxgi_screen_cap_src_debug);
-#endif
-
 static BOOL CALLBACK
 _diplay_monitor_enum (HMONITOR hMon, HDC hdc, LPRECT rect, LPARAM param)
 {
@@ -71,11 +65,6 @@ plugin_init (GstPlugin * plugin)
           GST_RANK_NONE, GST_TYPE_DX9SCREENCAPSRC)) {
     return FALSE;
   }
-#ifdef HAVE_DXGI_CAP
-  GST_DEBUG_CATEGORY_INIT (gst_dxgi_screen_cap_src_debug,
-      "dxgiscreencapsrc", 0, "DirectX DXGI screen capture source");
-  gst_dxgi_screen_cap_src_register (plugin, GST_RANK_NONE);
-#endif
 
   return TRUE;
 }
index 6700231..ee64ba3 100644 (file)
@@ -4,46 +4,26 @@ winscreencap_sources = [
   'gstwinscreencap.c',
 ]
 
-have_dxgi = false
-dxgi_c_args = []
-dxgiscreencap_sources = []
-dxgi_dep = []
-
 if host_system != 'windows' or get_option('winscreencap').disabled()
   subdir_done()
 endif
 
 d3d_dep = cc.find_library('d3d9', required : get_option('winscreencap'))
 gdi_dep = cc.find_library('gdi32', required : get_option('winscreencap'))
-d3d11_dep = cc.find_library('d3d11', required : false)
-dxgi_lib_dep = cc.find_library('dxgi', required : false)
 windowscodecs_dep = cc.find_library('windowscodecs',  required : false)
 dxguid_dep = cc.find_library('dxguid',  required : false)
 
-have_d3d11_h = cc.has_header('d3d11.h')
-have_dxgi_h = cc.has_header('dxgi1_2.h')
-have_d3dcompiler_h = cc.has_header('d3dcompiler.h')
-have_versionhelpers_h = cc.has_header('versionhelpers.h')
-
 have_d3d9_h = cc.has_header('d3d9.h')
 if not have_d3d9_h and get_option('winscreencap').enabled()
   error('winscreencap plugin enabled but d3d9.h not found')
 endif
 
-have_dxgi = d3d11_dep.found() and dxgi_lib_dep.found() and windowscodecs_dep.found() and dxguid_dep.found() and have_d3d11_h and have_dxgi_h and have_d3dcompiler_h and have_versionhelpers_h
-
-if have_dxgi
-  dxgi_c_args += ['-DHAVE_DXGI_CAP']
-  dxgiscreencap_sources += ['dxgicapture.c', 'gstdxgiscreencapsrc.c']
-  dxgi_dep += [gmodule_dep, d3d11_dep, dxgi_lib_dep, windowscodecs_dep, dxguid_dep]
-endif
-
 if d3d_dep.found() and gdi_dep.found() and have_d3d9_h
   gstwinscreencap = library('gstwinscreencap',
-    winscreencap_sources + dxgiscreencap_sources,
-    c_args : gst_plugins_bad_args + dxgi_c_args,
+    winscreencap_sources,
+    c_args : gst_plugins_bad_args,
     include_directories : [configinc],
-    dependencies : [gstbase_dep, gstvideo_dep, d3d_dep, gdi_dep] + dxgi_dep,
+    dependencies : [gstbase_dep, gstvideo_dep, d3d_dep, gdi_dep],
     install : true,
     install_dir : plugins_install_dir,
   )