d3d11: Rename screen capture element

Old name "desktopdup" may confuse users. Now it's renamed to
"screencapture"

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1136>
This commit is contained in:
Seungha Yang 2021-10-13 21:45:34 +09:00 committed by GStreamer Marge Bot
parent 5869855a98
commit b3710aa68d
11 changed files with 351 additions and 346 deletions

View file

@ -1,67 +0,0 @@
/*
* GStreamer
* Copyright (C) 2020 Seungha Yang <seungha@centricular.com>
*
* 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_D3D11_DESKTOP_DUP_H__
#define __GST_D3D11_DESKTOP_DUP_H__
#include <gst/gst.h>
#include <gst/video/video.h>
#include <gst/d3d11/gstd3d11.h>
G_BEGIN_DECLS
#define GST_D3D11_DESKTOP_DUP_FLOW_EXPECTED_ERROR GST_FLOW_CUSTOM_SUCCESS
#define GST_D3D11_DESKTOP_DUP_FLOW_SIZE_CHANGED GST_FLOW_CUSTOM_SUCCESS_1
#define GST_D3D11_DESKTOP_DUP_FLOW_UNSUPPORTED GST_FLOW_CUSTOM_ERROR
#define GST_TYPE_D3D11_DESKTOP_DUP (gst_d3d11_desktop_dup_get_type())
G_DECLARE_FINAL_TYPE (GstD3D11DesktopDup, gst_d3d11_desktop_dup,
GST, D3D11_DESKTOP_DUP, GstObject);
GstD3D11DesktopDup * gst_d3d11_desktop_dup_new (GstD3D11Device * device,
HMONITOR monitor_handle);
GstFlowReturn gst_d3d11_desktop_dup_prepare (GstD3D11DesktopDup * desktop);
gboolean gst_d3d11_desktop_dup_get_size (GstD3D11DesktopDup * desktop,
guint * width,
guint * height);
GstFlowReturn gst_d3d11_desktop_dup_capture (GstD3D11DesktopDup * desktop,
ID3D11Texture2D * texture,
ID3D11RenderTargetView *rtv,
gboolean draw_mouse);
HRESULT gst_d3d11_desktop_dup_find_output_for_monitor (HMONITOR monitor,
IDXGIAdapter1 ** adapter,
IDXGIOutput ** output);
HRESULT gst_d3d11_desktop_dup_find_primary_monitor (HMONITOR * monitor,
IDXGIAdapter1 ** adapter,
IDXGIOutput ** output);
HRESULT gst_d3d11_desktop_dup_find_nth_monitor (guint index,
HMONITOR * monitor,
IDXGIAdapter1 ** adapter,
IDXGIOutput ** output);
G_END_DECLS
#endif /* __GST_D3D11_DESKTOP_DUP_H__ */

View file

@ -46,20 +46,20 @@
#include "config.h"
#endif
#include "gstd3d11desktopdup.h"
#include "gstd3d11screencapture.h"
#include "gstd3d11shader.h"
#include "gstd3d11pluginutils.h"
#include <string.h>
#include <wrl.h>
GST_DEBUG_CATEGORY_EXTERN (gst_d3d11_desktop_dup_debug);
#define GST_CAT_DEFAULT gst_d3d11_desktop_dup_debug
GST_DEBUG_CATEGORY_EXTERN (gst_d3d11_screen_capture_debug);
#define GST_CAT_DEFAULT gst_d3d11_screen_capture_debug
/* *INDENT-OFF* */
using namespace Microsoft::WRL;
/* List of GstD3D11DesktopDup weakref */
/* List of GstD3D11ScreenCapture weakref */
G_LOCK_DEFINE_STATIC (dupl_list_lock);
static GList *dupl_list = nullptr;
@ -147,7 +147,7 @@ HRESULT EnumOutputsExpectedErrors[] = {
};
static GstFlowReturn
gst_d3d11_desktop_dup_return_from_hr (ID3D11Device * device,
gst_d3d11_screen_capture_return_from_hr (ID3D11Device * device,
HRESULT hr, HRESULT * expected_errors = nullptr)
{
HRESULT translated_hr = hr;
@ -181,7 +181,7 @@ gst_d3d11_desktop_dup_return_from_hr (ID3D11Device * device,
while (*rst != S_OK) {
if (*rst == translated_hr)
return GST_D3D11_DESKTOP_DUP_FLOW_EXPECTED_ERROR;
return GST_D3D11_SCREEN_CAPTURE_FLOW_EXPECTED_ERROR;
rst++;
}
@ -336,7 +336,7 @@ public:
HRESULT hr = dupl_->ReleaseFrame ();
if (!gst_d3d11_result (hr, device_)) {
GST_WARNING ("Couldn't release frame");
return gst_d3d11_desktop_dup_return_from_hr (nullptr, hr, FrameInfoExpectedErrors);
return gst_d3d11_screen_capture_return_from_hr (nullptr, hr, FrameInfoExpectedErrors);
}
GST_TRACE ("Capture done");
@ -661,7 +661,7 @@ private:
d3d11_device = gst_d3d11_device_get_device_handle (device);
HRESULT hr = gst_d3d11_desktop_dup_find_output_for_monitor (monitor,
HRESULT hr = gst_d3d11_screen_capture_find_output_for_monitor (monitor,
&adapter, &output);
if (!gst_d3d11_result (hr, device)) {
GST_ERROR ("Couldn't get adapter and output for monitor");
@ -701,10 +701,10 @@ private:
GST_WARNING ("IDXGIOutput1::DuplicateOutput returned "
"DXGI_ERROR_UNSUPPORTED, possiblely application is run against a "
"discrete GPU");
return GST_D3D11_DESKTOP_DUP_FLOW_UNSUPPORTED;
return GST_D3D11_SCREEN_CAPTURE_FLOW_UNSUPPORTED;
}
return gst_d3d11_desktop_dup_return_from_hr (d3d11_device.Get(), hr,
return gst_d3d11_screen_capture_return_from_hr (d3d11_device.Get(), hr,
CreateDuplicationExpectedErrors);
}
@ -746,7 +746,7 @@ private:
ID3D11Device *device_handle =
gst_d3d11_device_get_device_handle (device_);
return gst_d3d11_desktop_dup_return_from_hr(device_handle, hr,
return gst_d3d11_screen_capture_return_from_hr(device_handle, hr,
FrameInfoExpectedErrors);
}
@ -788,7 +788,7 @@ private:
*dirty_count = 0;
if (!gst_d3d11_result (hr, device_)) {
return gst_d3d11_desktop_dup_return_from_hr(device_handle, hr,
return gst_d3d11_screen_capture_return_from_hr(device_handle, hr,
FrameInfoExpectedErrors);
}
@ -831,7 +831,7 @@ private:
if (!gst_d3d11_result (hr, device_)) {
GST_ERROR ("Couldn't get move rect, hr 0x%x", (guint) hr);
return gst_d3d11_desktop_dup_return_from_hr(nullptr, hr,
return gst_d3d11_screen_capture_return_from_hr(nullptr, hr,
FrameInfoExpectedErrors);
}
@ -862,7 +862,7 @@ private:
*move_count = 0;
*dirty_count = 0;
return gst_d3d11_desktop_dup_return_from_hr(nullptr,
return gst_d3d11_screen_capture_return_from_hr(nullptr,
hr, FrameInfoExpectedErrors);
}
@ -1169,7 +1169,7 @@ private:
hr = device_handle->CreateShaderResourceView(SrcSurface,
&ShaderDesc, &ShaderResource);
if (!gst_d3d11_result (hr, device_)) {
return gst_d3d11_desktop_dup_return_from_hr(device_handle, hr,
return gst_d3d11_screen_capture_return_from_hr(device_handle, hr,
SystemTransitionsExpectedErrors);
}
@ -1457,7 +1457,7 @@ enum
#define DEFAULT_MONITOR_INDEX -1
struct _GstD3D11DesktopDup
struct _GstD3D11ScreenCapture
{
GstObject parent;
@ -1474,24 +1474,25 @@ struct _GstD3D11DesktopDup
GRecMutex lock;
};
static void gst_d3d11_desktop_dup_constructed (GObject * object);
static void gst_d3d11_desktop_dup_dispose (GObject * object);
static void gst_d3d11_desktop_dup_finalize (GObject * object);
static void gst_d3d11_desktop_dup_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_d3d11_screen_capture_constructed (GObject * object);
static void gst_d3d11_screen_capture_dispose (GObject * object);
static void gst_d3d11_screen_capture_finalize (GObject * object);
static void gst_d3d11_screen_capture_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec);
#define gst_d3d11_desktop_dup_parent_class parent_class
G_DEFINE_TYPE (GstD3D11DesktopDup, gst_d3d11_desktop_dup, GST_TYPE_OBJECT);
#define gst_d3d11_screen_capture_parent_class parent_class
G_DEFINE_TYPE (GstD3D11ScreenCapture, gst_d3d11_screen_capture,
GST_TYPE_OBJECT);
static void
gst_d3d11_desktop_dup_class_init (GstD3D11DesktopDupClass * klass)
gst_d3d11_screen_capture_class_init (GstD3D11ScreenCaptureClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->constructed = gst_d3d11_desktop_dup_constructed;
gobject_class->dispose = gst_d3d11_desktop_dup_dispose;
gobject_class->finalize = gst_d3d11_desktop_dup_finalize;
gobject_class->set_property = gst_d3d11_desktop_dup_set_property;
gobject_class->constructed = gst_d3d11_screen_capture_constructed;
gobject_class->dispose = gst_d3d11_screen_capture_dispose;
gobject_class->finalize = gst_d3d11_screen_capture_finalize;
gobject_class->set_property = gst_d3d11_screen_capture_set_property;
g_object_class_install_property (gobject_class, PROP_D3D11_DEVICE,
g_param_spec_object ("d3d11device", "D3D11 Device",
@ -1507,7 +1508,7 @@ gst_d3d11_desktop_dup_class_init (GstD3D11DesktopDupClass * klass)
}
static void
gst_d3d11_desktop_dup_init (GstD3D11DesktopDup * self)
gst_d3d11_screen_capture_init (GstD3D11ScreenCapture * self)
{
g_rec_mutex_init (&self->lock);
@ -1515,9 +1516,9 @@ gst_d3d11_desktop_dup_init (GstD3D11DesktopDup * self)
}
static void
gst_d3d11_desktop_dup_constructed (GObject * object)
gst_d3d11_screen_capture_constructed (GObject * object)
{
GstD3D11DesktopDup *self = GST_D3D11_DESKTOP_DUP (object);
GstD3D11ScreenCapture *self = GST_D3D11_SCREEN_CAPTURE (object);
/* *INDENT-OFF* */
ComPtr<IDXGIDevice> dxgi_device;
ComPtr<IDXGIAdapter1> adapter;
@ -1540,7 +1541,7 @@ gst_d3d11_desktop_dup_constructed (GObject * object)
goto out;
}
hr = gst_d3d11_desktop_dup_find_output_for_monitor (self->monitor_handle,
hr = gst_d3d11_screen_capture_find_output_for_monitor (self->monitor_handle,
&adapter, &output);
if (!gst_d3d11_result (hr, self->device)) {
GST_WARNING_OBJECT (self,
@ -1623,10 +1624,10 @@ out:
}
static void
gst_d3d11_desktop_dup_set_property (GObject * object, guint prop_id,
gst_d3d11_screen_capture_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstD3D11DesktopDup *self = GST_D3D11_DESKTOP_DUP (object);
GstD3D11ScreenCapture *self = GST_D3D11_SCREEN_CAPTURE (object);
switch (prop_id) {
case PROP_D3D11_DEVICE:
@ -1642,9 +1643,9 @@ gst_d3d11_desktop_dup_set_property (GObject * object, guint prop_id,
}
static void
gst_d3d11_desktop_dup_dispose (GObject * object)
gst_d3d11_screen_capture_dispose (GObject * object)
{
GstD3D11DesktopDup *self = GST_D3D11_DESKTOP_DUP (object);
GstD3D11ScreenCapture *self = GST_D3D11_SCREEN_CAPTURE (object);
if (self->dupl_obj) {
delete self->dupl_obj;
@ -1657,9 +1658,9 @@ gst_d3d11_desktop_dup_dispose (GObject * object)
}
static void
gst_d3d11_desktop_dup_finalize (GObject * object)
gst_d3d11_screen_capture_finalize (GObject * object)
{
GstD3D11DesktopDup *self = GST_D3D11_DESKTOP_DUP (object);
GstD3D11ScreenCapture *self = GST_D3D11_SCREEN_CAPTURE (object);
g_rec_mutex_clear (&self->lock);
@ -1667,17 +1668,18 @@ gst_d3d11_desktop_dup_finalize (GObject * object)
}
static void
gst_d3d11_desktop_dup_weak_ref_notify (gpointer data, GstD3D11DesktopDup * dupl)
gst_d3d11_screen_capture_weak_ref_notify (gpointer data,
GstD3D11ScreenCapture * dupl)
{
G_LOCK (dupl_list_lock);
dupl_list = g_list_remove (dupl_list, dupl);
G_UNLOCK (dupl_list_lock);
}
GstD3D11DesktopDup *
gst_d3d11_desktop_dup_new (GstD3D11Device * device, HMONITOR monitor_handle)
GstD3D11ScreenCapture *
gst_d3d11_screen_capture_new (GstD3D11Device * device, HMONITOR monitor_handle)
{
GstD3D11DesktopDup *self = nullptr;
GstD3D11ScreenCapture *self = nullptr;
GList *iter;
g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), nullptr);
@ -1691,12 +1693,12 @@ gst_d3d11_desktop_dup_new (GstD3D11Device * device, HMONITOR monitor_handle)
*/
G_LOCK (dupl_list_lock);
for (iter = dupl_list; iter; iter = g_list_next (iter)) {
GstD3D11DesktopDup *dupl = (GstD3D11DesktopDup *) iter->data;
GstD3D11ScreenCapture *dupl = (GstD3D11ScreenCapture *) iter->data;
if (dupl->monitor_handle == monitor_handle) {
GST_DEBUG ("Found configured desktop dup object for monitor handle %p",
monitor_handle);
self = (GstD3D11DesktopDup *) gst_object_ref (dupl);
self = (GstD3D11ScreenCapture *) gst_object_ref (dupl);
break;
}
}
@ -1706,7 +1708,7 @@ gst_d3d11_desktop_dup_new (GstD3D11Device * device, HMONITOR monitor_handle)
return self;
}
self = (GstD3D11DesktopDup *) g_object_new (GST_TYPE_D3D11_DESKTOP_DUP,
self = (GstD3D11ScreenCapture *) g_object_new (GST_TYPE_D3D11_SCREEN_CAPTURE,
"d3d11device", device, "monitor-handle", monitor_handle, nullptr);
if (!self->device) {
@ -1718,7 +1720,7 @@ gst_d3d11_desktop_dup_new (GstD3D11Device * device, HMONITOR monitor_handle)
}
g_object_weak_ref (G_OBJECT (self),
(GWeakNotify) gst_d3d11_desktop_dup_weak_ref_notify, nullptr);
(GWeakNotify) gst_d3d11_screen_capture_weak_ref_notify, nullptr);
dupl_list = g_list_append (dupl_list, self);
G_UNLOCK (dupl_list_lock);
@ -1727,66 +1729,66 @@ gst_d3d11_desktop_dup_new (GstD3D11Device * device, HMONITOR monitor_handle)
}
GstFlowReturn
gst_d3d11_desktop_dup_prepare (GstD3D11DesktopDup * desktop)
gst_d3d11_screen_capture_prepare (GstD3D11ScreenCapture * capture)
{
GstFlowReturn ret;
g_return_val_if_fail (GST_IS_D3D11_DESKTOP_DUP (desktop), GST_FLOW_ERROR);
g_return_val_if_fail (desktop->device != nullptr, GST_FLOW_ERROR);
g_return_val_if_fail (GST_IS_D3D11_SCREEN_CAPTURE (capture), GST_FLOW_ERROR);
g_return_val_if_fail (capture->device != nullptr, GST_FLOW_ERROR);
g_rec_mutex_lock (&desktop->lock);
if (desktop->prepared) {
GST_DEBUG_OBJECT (desktop, "Already prepared");
g_rec_mutex_unlock (&desktop->lock);
g_rec_mutex_lock (&capture->lock);
if (capture->prepared) {
GST_DEBUG_OBJECT (capture, "Already prepared");
g_rec_mutex_unlock (&capture->lock);
return GST_FLOW_OK;
}
desktop->dupl_obj = new D3D11DesktopDupObject ();
ret = desktop->dupl_obj->Init (desktop->device, desktop->monitor_handle);
capture->dupl_obj = new D3D11DesktopDupObject ();
ret = capture->dupl_obj->Init (capture->device, capture->monitor_handle);
if (ret != GST_FLOW_OK) {
GST_WARNING_OBJECT (desktop,
GST_WARNING_OBJECT (capture,
"Couldn't prepare capturing, %sexpected failure",
ret == GST_D3D11_DESKTOP_DUP_FLOW_EXPECTED_ERROR ? "" : "un");
ret == GST_D3D11_SCREEN_CAPTURE_FLOW_EXPECTED_ERROR ? "" : "un");
delete desktop->dupl_obj;
desktop->dupl_obj = nullptr;
g_rec_mutex_unlock (&desktop->lock);
delete capture->dupl_obj;
capture->dupl_obj = nullptr;
g_rec_mutex_unlock (&capture->lock);
return ret;
}
desktop->prepared = TRUE;
g_rec_mutex_unlock (&desktop->lock);
capture->prepared = TRUE;
g_rec_mutex_unlock (&capture->lock);
return GST_FLOW_OK;
}
gboolean
gst_d3d11_desktop_dup_get_size (GstD3D11DesktopDup * desktop, guint * width,
guint * height)
gst_d3d11_screen_capture_get_size (GstD3D11ScreenCapture * capture,
guint * width, guint * height)
{
g_return_val_if_fail (GST_IS_D3D11_DESKTOP_DUP (desktop), FALSE);
g_return_val_if_fail (GST_IS_D3D11_SCREEN_CAPTURE (capture), FALSE);
g_return_val_if_fail (width != nullptr, FALSE);
g_return_val_if_fail (height != nullptr, FALSE);
g_rec_mutex_lock (&desktop->lock);
g_rec_mutex_lock (&capture->lock);
*width = 0;
*height = 0;
if (desktop->dupl_obj) {
desktop->dupl_obj->GetSize (&desktop->cached_width,
&desktop->cached_height);
if (capture->dupl_obj) {
capture->dupl_obj->GetSize (&capture->cached_width,
&capture->cached_height);
}
*width = desktop->cached_width;
*height = desktop->cached_height;
g_rec_mutex_unlock (&desktop->lock);
*width = capture->cached_width;
*height = capture->cached_height;
g_rec_mutex_unlock (&capture->lock);
return TRUE;
}
GstFlowReturn
gst_d3d11_desktop_dup_capture (GstD3D11DesktopDup * desktop,
gst_d3d11_screen_capture_do_capture (GstD3D11ScreenCapture * capture,
ID3D11Texture2D * texture, ID3D11RenderTargetView * rtv,
gboolean draw_mouse)
{
@ -1794,64 +1796,64 @@ gst_d3d11_desktop_dup_capture (GstD3D11DesktopDup * desktop,
D3D11_TEXTURE2D_DESC desc;
guint width, height;
g_return_val_if_fail (GST_IS_D3D11_DESKTOP_DUP (desktop), GST_FLOW_ERROR);
g_return_val_if_fail (GST_IS_D3D11_SCREEN_CAPTURE (capture), GST_FLOW_ERROR);
g_return_val_if_fail (texture != nullptr, GST_FLOW_ERROR);
g_rec_mutex_lock (&desktop->lock);
if (!desktop->prepared)
ret = gst_d3d11_desktop_dup_prepare (desktop);
g_rec_mutex_lock (&capture->lock);
if (!capture->prepared)
ret = gst_d3d11_screen_capture_prepare (capture);
if (ret != GST_FLOW_OK) {
GST_WARNING_OBJECT (desktop, "We are not prepared");
g_rec_mutex_unlock (&desktop->lock);
GST_WARNING_OBJECT (capture, "We are not prepared");
g_rec_mutex_unlock (&capture->lock);
return ret;
}
gst_d3d11_desktop_dup_get_size (desktop, &width, &height);
gst_d3d11_screen_capture_get_size (capture, &width, &height);
texture->GetDesc (&desc);
if (desc.Width != width || desc.Height != height) {
GST_INFO_OBJECT (desktop,
GST_INFO_OBJECT (capture,
"Different texture size, ours: %dx%d, external: %dx%d",
width, height, desc.Width, desc.Height);
g_rec_mutex_unlock (&desktop->lock);
g_rec_mutex_unlock (&capture->lock);
return GST_D3D11_DESKTOP_DUP_FLOW_SIZE_CHANGED;
return GST_D3D11_SCREEN_CAPTURE_FLOW_SIZE_CHANGED;
}
gst_d3d11_device_lock (desktop->device);
ret = desktop->dupl_obj->Capture (draw_mouse);
gst_d3d11_device_lock (capture->device);
ret = capture->dupl_obj->Capture (draw_mouse);
if (ret != GST_FLOW_OK) {
gst_d3d11_device_unlock (desktop->device);
gst_d3d11_device_unlock (capture->device);
delete desktop->dupl_obj;
desktop->dupl_obj = nullptr;
desktop->prepared = FALSE;
delete capture->dupl_obj;
capture->dupl_obj = nullptr;
capture->prepared = FALSE;
if (ret == GST_D3D11_DESKTOP_DUP_FLOW_EXPECTED_ERROR) {
GST_WARNING_OBJECT (desktop,
if (ret == GST_D3D11_SCREEN_CAPTURE_FLOW_EXPECTED_ERROR) {
GST_WARNING_OBJECT (capture,
"Couldn't capture frame, but expected failure");
} else {
GST_ERROR_OBJECT (desktop, "Unexpected failure during capture");
GST_ERROR_OBJECT (capture, "Unexpected failure during capture");
}
g_rec_mutex_unlock (&desktop->lock);
g_rec_mutex_unlock (&capture->lock);
return ret;
}
GST_LOG_OBJECT (desktop, "Capture done");
GST_LOG_OBJECT (capture, "Capture done");
desktop->dupl_obj->CopyToTexture (texture);
capture->dupl_obj->CopyToTexture (texture);
if (draw_mouse)
desktop->dupl_obj->DrawMouse (rtv);
gst_d3d11_device_unlock (desktop->device);
g_rec_mutex_unlock (&desktop->lock);
capture->dupl_obj->DrawMouse (rtv);
gst_d3d11_device_unlock (capture->device);
g_rec_mutex_unlock (&capture->lock);
return GST_FLOW_OK;
}
HRESULT
gst_d3d11_desktop_dup_find_output_for_monitor (HMONITOR monitor,
gst_d3d11_screen_capture_find_output_for_monitor (HMONITOR monitor,
IDXGIAdapter1 ** adapter, IDXGIOutput ** output)
{
ComPtr < IDXGIFactory1 > factory;
@ -1897,7 +1899,7 @@ gst_d3d11_desktop_dup_find_output_for_monitor (HMONITOR monitor,
}
HRESULT
gst_d3d11_desktop_dup_find_primary_monitor (HMONITOR * monitor,
gst_d3d11_screen_capture_find_primary_monitor (HMONITOR * monitor,
IDXGIAdapter1 ** adapter, IDXGIOutput ** output)
{
ComPtr < IDXGIFactory1 > factory;
@ -1948,7 +1950,7 @@ gst_d3d11_desktop_dup_find_primary_monitor (HMONITOR * monitor,
}
HRESULT
gst_d3d11_desktop_dup_find_nth_monitor (guint index, HMONITOR * monitor,
gst_d3d11_screen_capture_find_nth_monitor (guint index, HMONITOR * monitor,
IDXGIAdapter1 ** adapter, IDXGIOutput ** output)
{
ComPtr < IDXGIFactory1 > factory;

View file

@ -0,0 +1,65 @@
/*
* GStreamer
* Copyright (C) 2020 Seungha Yang <seungha@centricular.com>
*
* 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.
*/
#pragma once
#include <gst/gst.h>
#include <gst/video/video.h>
#include <gst/d3d11/gstd3d11.h>
G_BEGIN_DECLS
#define GST_D3D11_SCREEN_CAPTURE_FLOW_EXPECTED_ERROR GST_FLOW_CUSTOM_SUCCESS
#define GST_D3D11_SCREEN_CAPTURE_FLOW_SIZE_CHANGED GST_FLOW_CUSTOM_SUCCESS_1
#define GST_D3D11_SCREEN_CAPTURE_FLOW_UNSUPPORTED GST_FLOW_CUSTOM_ERROR
#define GST_TYPE_D3D11_SCREEN_CAPTURE (gst_d3d11_screen_capture_get_type())
G_DECLARE_FINAL_TYPE (GstD3D11ScreenCapture, gst_d3d11_screen_capture,
GST, D3D11_SCREEN_CAPTURE, GstObject);
GstD3D11ScreenCapture * gst_d3d11_screen_capture_new (GstD3D11Device * device,
HMONITOR monitor_handle);
GstFlowReturn gst_d3d11_screen_capture_prepare (GstD3D11ScreenCapture * capture);
gboolean gst_d3d11_screen_capture_get_size (GstD3D11ScreenCapture * capture,
guint * width,
guint * height);
GstFlowReturn gst_d3d11_screen_capture_do_capture (GstD3D11ScreenCapture * capture,
ID3D11Texture2D * texture,
ID3D11RenderTargetView *rtv,
gboolean draw_mouse);
HRESULT gst_d3d11_screen_capture_find_output_for_monitor (HMONITOR monitor,
IDXGIAdapter1 ** adapter,
IDXGIOutput ** output);
HRESULT gst_d3d11_screen_capture_find_primary_monitor (HMONITOR * monitor,
IDXGIAdapter1 ** adapter,
IDXGIOutput ** output);
HRESULT gst_d3d11_screen_capture_find_nth_monitor (guint index,
HMONITOR * monitor,
IDXGIAdapter1 ** adapter,
IDXGIOutput ** output);
G_END_DECLS

View file

@ -21,7 +21,7 @@
#include "config.h"
#endif
#include "gstd3d11desktopdupdevice.h"
#include "gstd3d11screencapturedevice.h"
#include <gst/d3d11/gstd3d11.h>
#include <gst/video/video.h>
#include <wrl.h>
@ -34,8 +34,8 @@
using namespace Microsoft::WRL;
/* *INDENT-ON* */
GST_DEBUG_CATEGORY_EXTERN (gst_d3d11_desktop_dup_device_debug);
#define GST_CAT_DEFAULT gst_d3d11_desktop_dup_device_debug
GST_DEBUG_CATEGORY_EXTERN (gst_d3d11_screen_capture_device_debug);
#define GST_CAT_DEFAULT gst_d3d11_screen_capture_device_debug
static GstStaticCaps template_caps =
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
@ -48,31 +48,32 @@ enum
PROP_MONITOR_HANDLE,
};
struct _GstD3D11DesktopDupDevice
struct _GstD3D11ScreenCaptureDevice
{
GstDevice parent;
HMONITOR monitor_handle;
};
static void gst_d3d11_desktop_dup_device_get_property (GObject * object,
static void gst_d3d11_screen_capture_device_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec);
static void gst_d3d11_desktop_dup_device_set_property (GObject * object,
static void gst_d3d11_screen_capture_device_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec);
static GstElement *gst_d3d11_desktop_dup_device_create_element (GstDevice *
static GstElement *gst_d3d11_screen_capture_device_create_element (GstDevice *
device, const gchar * name);
G_DEFINE_TYPE (GstD3D11DesktopDupDevice,
gst_d3d11_desktop_dup_device, GST_TYPE_DEVICE);
G_DEFINE_TYPE (GstD3D11ScreenCaptureDevice,
gst_d3d11_screen_capture_device, GST_TYPE_DEVICE);
static void
gst_d3d11_desktop_dup_device_class_init (GstD3D11DesktopDupDeviceClass * klass)
gst_d3d11_screen_capture_device_class_init (GstD3D11ScreenCaptureDeviceClass *
klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GstDeviceClass *dev_class = GST_DEVICE_CLASS (klass);
object_class->get_property = gst_d3d11_desktop_dup_device_get_property;
object_class->set_property = gst_d3d11_desktop_dup_device_set_property;
object_class->get_property = gst_d3d11_screen_capture_device_get_property;
object_class->set_property = gst_d3d11_screen_capture_device_set_property;
g_object_class_install_property (object_class, PROP_MONITOR_HANDLE,
g_param_spec_uint64 ("monitor-handle", "Monitor Handle",
@ -81,19 +82,19 @@ gst_d3d11_desktop_dup_device_class_init (GstD3D11DesktopDupDeviceClass * klass)
G_PARAM_CONSTRUCT_ONLY)));
dev_class->create_element = gst_d3d11_desktop_dup_device_create_element;
dev_class->create_element = gst_d3d11_screen_capture_device_create_element;
}
static void
gst_d3d11_desktop_dup_device_init (GstD3D11DesktopDupDevice * self)
gst_d3d11_screen_capture_device_init (GstD3D11ScreenCaptureDevice * self)
{
}
static void
gst_d3d11_desktop_dup_device_get_property (GObject * object, guint prop_id,
gst_d3d11_screen_capture_device_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstD3D11DesktopDupDevice *self = GST_D3D11_DESKTOP_DUP_DEVICE (object);
GstD3D11ScreenCaptureDevice *self = GST_D3D11_SCREEN_CAPTURE_DEVICE (object);
switch (prop_id) {
case PROP_MONITOR_HANDLE:
@ -106,10 +107,10 @@ gst_d3d11_desktop_dup_device_get_property (GObject * object, guint prop_id,
}
static void
gst_d3d11_desktop_dup_device_set_property (GObject * object, guint prop_id,
gst_d3d11_screen_capture_device_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstD3D11DesktopDupDevice *self = GST_D3D11_DESKTOP_DUP_DEVICE (object);
GstD3D11ScreenCaptureDevice *self = GST_D3D11_SCREEN_CAPTURE_DEVICE (object);
switch (prop_id) {
case PROP_MONITOR_HANDLE:
@ -122,38 +123,38 @@ gst_d3d11_desktop_dup_device_set_property (GObject * object, guint prop_id,
}
static GstElement *
gst_d3d11_desktop_dup_device_create_element (GstDevice * device,
gst_d3d11_screen_capture_device_create_element (GstDevice * device,
const gchar * name)
{
GstD3D11DesktopDupDevice *self = GST_D3D11_DESKTOP_DUP_DEVICE (device);
GstD3D11ScreenCaptureDevice *self = GST_D3D11_SCREEN_CAPTURE_DEVICE (device);
GstElement *elem;
elem = gst_element_factory_make ("d3d11desktopdupsrc", name);
elem = gst_element_factory_make ("d3d11screencapturesrc", name);
g_object_set (elem, "monitor-handle", self->monitor_handle, NULL);
g_object_set (elem, "monitor-handle", self->monitor_handle, nullptr);
return elem;
}
struct _GstD3D11DesktopDupDeviceProvider
struct _GstD3D11ScreenCaptureDeviceProvider
{
GstDeviceProvider parent;
};
G_DEFINE_TYPE (GstD3D11DesktopDupDeviceProvider,
gst_d3d11_desktop_dup_device_provider, GST_TYPE_DEVICE_PROVIDER);
G_DEFINE_TYPE (GstD3D11ScreenCaptureDeviceProvider,
gst_d3d11_screen_capture_device_provider, GST_TYPE_DEVICE_PROVIDER);
static GList *gst_d3d11_desktop_dup_device_provider_probe (GstDeviceProvider *
provider);
static GList *gst_d3d11_screen_capture_device_provider_probe (GstDeviceProvider
* provider);
static void
gst_d3d11_desktop_dup_device_provider_class_init
(GstD3D11DesktopDupDeviceProviderClass * klass)
gst_d3d11_screen_capture_device_provider_class_init
(GstD3D11ScreenCaptureDeviceProviderClass * klass)
{
GstDeviceProviderClass *provider_class = GST_DEVICE_PROVIDER_CLASS (klass);
provider_class->probe =
GST_DEBUG_FUNCPTR (gst_d3d11_desktop_dup_device_provider_probe);
GST_DEBUG_FUNCPTR (gst_d3d11_screen_capture_device_provider_probe);
gst_device_provider_class_set_static_metadata (provider_class,
"Direct3D11 Desktop Capture Device Provider",
@ -162,8 +163,8 @@ static void
}
static void
gst_d3d11_desktop_dup_device_provider_init (GstD3D11DesktopDupDeviceProvider *
self)
gst_d3d11_screen_capture_device_provider_init
(GstD3D11ScreenCaptureDeviceProvider * self)
{
}
@ -341,7 +342,7 @@ create_device (const DXGI_ADAPTER_DESC * adapter_desc,
if ((minfo->dwFlags & MONITORINFOF_PRIMARY) != 0)
primary = TRUE;
props = gst_structure_new ("d3d11desktopdupdevice-proplist",
props = gst_structure_new ("d3d11screencapturedevice-proplist",
"device.api", G_TYPE_STRING, "d3d11",
"device.name", G_TYPE_STRING, GST_STR_NULL (device_name.c_str ()),
"device.path", G_TYPE_STRING, GST_STR_NULL (device_path.c_str ()),
@ -365,7 +366,7 @@ create_device (const DXGI_ADAPTER_DESC * adapter_desc,
"display.coordinates.right", G_TYPE_INT, right,
"display.coordinates.bottom", G_TYPE_INT, bottom, nullptr);
device = (GstDevice *) g_object_new (GST_TYPE_D3D11_DESKTOP_DUP_DEVICE,
device = (GstDevice *) g_object_new (GST_TYPE_D3D11_SCREEN_CAPTURE_DEVICE,
"display-name", display_name.c_str (), "caps", caps, "device-class",
"Source/Monitor", "properties", props, "monitor-handle",
(guint64) output_desc->Monitor, nullptr);
@ -376,7 +377,7 @@ create_device (const DXGI_ADAPTER_DESC * adapter_desc,
}
static GList *
gst_d3d11_desktop_dup_device_provider_probe (GstDeviceProvider * provider)
gst_d3d11_screen_capture_device_provider_probe (GstDeviceProvider * provider)
{
GList *devices = nullptr;
ComPtr < IDXGIFactory1 > factory;

View file

@ -23,14 +23,14 @@
G_BEGIN_DECLS
#define GST_TYPE_D3D11_DESKTOP_DUP_DEVICE (gst_d3d11_desktop_dup_device_get_type())
G_DECLARE_FINAL_TYPE (GstD3D11DesktopDupDevice, gst_d3d11_desktop_dup_device,
GST, D3D11_DESKTOP_DUP_DEVICE, GstDevice);
#define GST_TYPE_D3D11_SCREEN_CAPTURE_DEVICE (gst_d3d11_screen_capture_device_get_type())
G_DECLARE_FINAL_TYPE (GstD3D11ScreenCaptureDevice, gst_d3d11_screen_capture_device,
GST, D3D11_SCREEN_CAPTURE_DEVICE, GstDevice);
#define GST_TYPE_D3D11_DESKTOP_DUP_DEVICE_PROVIDER (gst_d3d11_desktop_dup_device_provider_get_type())
G_DECLARE_FINAL_TYPE (GstD3D11DesktopDupDeviceProvider,
gst_d3d11_desktop_dup_device_provider,
GST, D3D11_DESKTOP_DUP_DEVICE_PROVIDER, GstDeviceProvider);
#define GST_TYPE_D3D11_SCREEN_CAPTURE_DEVICE_PROVIDER (gst_d3d11_screen_capture_device_provider_get_type())
G_DECLARE_FINAL_TYPE (GstD3D11ScreenCaptureDeviceProvider,
gst_d3d11_screen_capture_device_provider,
GST, D3D11_SCREEN_CAPTURE_DEVICE_PROVIDER, GstDeviceProvider);
G_END_DECLS

View file

@ -19,14 +19,14 @@
*/
/**
* SECTION:element-d3d11desktopdupsrc
* @title: d3d11desktopdupsrc
* SECTION:element-d3d11screencapturesrc
* @title: d3d11screencapturesrc
*
* A DXGI Desktop Duplication API based screen capture element
*
* ## Example launch line
* ```
* gst-launch-1.0 d3d11desktopdupsrc ! queue ! d3d11videosink
* gst-launch-1.0 d3d11screencapturesrc ! queue ! d3d11videosink
* ```
*
* Since: 1.20
@ -36,8 +36,8 @@
#include "config.h"
#endif
#include "gstd3d11desktopdupsrc.h"
#include "gstd3d11desktopdup.h"
#include "gstd3d11screencapturesrc.h"
#include "gstd3d11screencapture.h"
#include "gstd3d11pluginutils.h"
#include <wrl.h>
#include <string.h>
@ -46,8 +46,8 @@
using namespace Microsoft::WRL;
/* *INDENT-ON* */
GST_DEBUG_CATEGORY_EXTERN (gst_d3d11_desktop_dup_debug);
#define GST_CAT_DEFAULT gst_d3d11_desktop_dup_debug
GST_DEBUG_CATEGORY_EXTERN (gst_d3d11_screen_capture_debug);
#define GST_CAT_DEFAULT gst_d3d11_screen_capture_debug
enum
{
@ -69,7 +69,7 @@ static GstStaticCaps template_caps =
(GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, "BGRA") ";"
GST_VIDEO_CAPS_MAKE ("BGRA"));
struct _GstD3D11DesktopDupSrc
struct _GstD3D11ScreenCaptureSrc
{
GstBaseSrc src;
@ -78,7 +78,7 @@ struct _GstD3D11DesktopDupSrc
GstVideoInfo video_info;
GstD3D11Device *device;
GstD3D11DesktopDup *dupl;
GstD3D11ScreenCapture *capture;
GstBufferPool *pool;
@ -94,48 +94,48 @@ struct _GstD3D11DesktopDupSrc
gboolean downstream_supports_d3d11;
};
static void gst_d3d11_desktop_dup_src_dispose (GObject * object);
static void gst_d3d11_desktop_dup_src_set_property (GObject * object,
static void gst_d3d11_screen_capture_src_dispose (GObject * object);
static void gst_d3d11_screen_capture_src_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_d3d11_desktop_dup_src_get_property (GObject * object,
static void gst_d3d11_screen_capture_src_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec);
static void gst_d3d11_desktop_dup_src_set_context (GstElement * element,
static void gst_d3d11_screen_capture_src_set_context (GstElement * element,
GstContext * context);
static GstCaps *gst_d3d11_desktop_dup_src_get_caps (GstBaseSrc * bsrc,
static GstCaps *gst_d3d11_screen_capture_src_get_caps (GstBaseSrc * bsrc,
GstCaps * filter);
static GstCaps *gst_d3d11_desktop_dup_src_fixate (GstBaseSrc * bsrc,
static GstCaps *gst_d3d11_screen_capture_src_fixate (GstBaseSrc * bsrc,
GstCaps * caps);
static gboolean gst_d3d11_desktop_dup_src_set_caps (GstBaseSrc * bsrc,
static gboolean gst_d3d11_screen_capture_src_set_caps (GstBaseSrc * bsrc,
GstCaps * caps);
static gboolean gst_d3d11_desktop_dup_src_decide_allocation (GstBaseSrc * bsrc,
GstQuery * query);
static gboolean gst_d3d11_desktop_dup_src_start (GstBaseSrc * bsrc);
static gboolean gst_d3d11_desktop_dup_src_stop (GstBaseSrc * bsrc);
static gboolean gst_d3d11_desktop_dup_src_unlock (GstBaseSrc * bsrc);
static gboolean gst_d3d11_desktop_dup_src_unlock_stop (GstBaseSrc * bsrc);
static gboolean gst_d3d11_screen_capture_src_decide_allocation (GstBaseSrc *
bsrc, GstQuery * query);
static gboolean gst_d3d11_screen_capture_src_start (GstBaseSrc * bsrc);
static gboolean gst_d3d11_screen_capture_src_stop (GstBaseSrc * bsrc);
static gboolean gst_d3d11_screen_capture_src_unlock (GstBaseSrc * bsrc);
static gboolean gst_d3d11_screen_capture_src_unlock_stop (GstBaseSrc * bsrc);
static gboolean
gst_d3d11_desktop_dup_src_src_query (GstBaseSrc * bsrc, GstQuery * query);
gst_d3d11_screen_capture_src_src_query (GstBaseSrc * bsrc, GstQuery * query);
static GstFlowReturn gst_d3d11_desktop_dup_src_create (GstBaseSrc * bsrc,
static GstFlowReturn gst_d3d11_screen_capture_src_create (GstBaseSrc * bsrc,
guint64 offset, guint size, GstBuffer ** buf);
#define gst_d3d11_desktop_dup_src_parent_class parent_class
G_DEFINE_TYPE (GstD3D11DesktopDupSrc, gst_d3d11_desktop_dup_src,
#define gst_d3d11_screen_capture_src_parent_class parent_class
G_DEFINE_TYPE (GstD3D11ScreenCaptureSrc, gst_d3d11_screen_capture_src,
GST_TYPE_BASE_SRC);
static void
gst_d3d11_desktop_dup_src_class_init (GstD3D11DesktopDupSrcClass * klass)
gst_d3d11_screen_capture_src_class_init (GstD3D11ScreenCaptureSrcClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstBaseSrcClass *basesrc_class = GST_BASE_SRC_CLASS (klass);
GstCaps *caps;
gobject_class->dispose = gst_d3d11_desktop_dup_src_dispose;
gobject_class->set_property = gst_d3d11_desktop_dup_src_set_property;
gobject_class->get_property = gst_d3d11_desktop_dup_src_get_property;
gobject_class->dispose = gst_d3d11_screen_capture_src_dispose;
gobject_class->set_property = gst_d3d11_screen_capture_src_set_property;
gobject_class->get_property = gst_d3d11_screen_capture_src_get_property;
properties[PROP_MONITOR_INDEX] =
g_param_spec_int ("monitor-index", "Monitor Index",
@ -160,10 +160,10 @@ gst_d3d11_desktop_dup_src_class_init (GstD3D11DesktopDupSrcClass * klass)
g_object_class_install_properties (gobject_class, PROP_LAST, properties);
element_class->set_context =
GST_DEBUG_FUNCPTR (gst_d3d11_desktop_dup_src_set_context);
GST_DEBUG_FUNCPTR (gst_d3d11_screen_capture_src_set_context);
gst_element_class_set_static_metadata (element_class,
"Direct3D11 desktop duplication src", "Source/Video",
"Direct3D11 screen capture src", "Source/Video",
"Capture desktop image by using Desktop Duplication API",
"Seungha Yang <seungha@centricular.com>");
@ -173,25 +173,28 @@ gst_d3d11_desktop_dup_src_class_init (GstD3D11DesktopDupSrcClass * klass)
gst_caps_unref (caps);
basesrc_class->get_caps =
GST_DEBUG_FUNCPTR (gst_d3d11_desktop_dup_src_get_caps);
basesrc_class->fixate = GST_DEBUG_FUNCPTR (gst_d3d11_desktop_dup_src_fixate);
GST_DEBUG_FUNCPTR (gst_d3d11_screen_capture_src_get_caps);
basesrc_class->fixate =
GST_DEBUG_FUNCPTR (gst_d3d11_screen_capture_src_fixate);
basesrc_class->set_caps =
GST_DEBUG_FUNCPTR (gst_d3d11_desktop_dup_src_set_caps);
GST_DEBUG_FUNCPTR (gst_d3d11_screen_capture_src_set_caps);
basesrc_class->decide_allocation =
GST_DEBUG_FUNCPTR (gst_d3d11_desktop_dup_src_decide_allocation);
basesrc_class->start = GST_DEBUG_FUNCPTR (gst_d3d11_desktop_dup_src_start);
basesrc_class->stop = GST_DEBUG_FUNCPTR (gst_d3d11_desktop_dup_src_stop);
basesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_d3d11_desktop_dup_src_unlock);
GST_DEBUG_FUNCPTR (gst_d3d11_screen_capture_src_decide_allocation);
basesrc_class->start = GST_DEBUG_FUNCPTR (gst_d3d11_screen_capture_src_start);
basesrc_class->stop = GST_DEBUG_FUNCPTR (gst_d3d11_screen_capture_src_stop);
basesrc_class->unlock =
GST_DEBUG_FUNCPTR (gst_d3d11_screen_capture_src_unlock);
basesrc_class->unlock_stop =
GST_DEBUG_FUNCPTR (gst_d3d11_desktop_dup_src_unlock_stop);
GST_DEBUG_FUNCPTR (gst_d3d11_screen_capture_src_unlock_stop);
basesrc_class->query =
GST_DEBUG_FUNCPTR (gst_d3d11_desktop_dup_src_src_query);
GST_DEBUG_FUNCPTR (gst_d3d11_screen_capture_src_src_query);
basesrc_class->create = GST_DEBUG_FUNCPTR (gst_d3d11_desktop_dup_src_create);
basesrc_class->create =
GST_DEBUG_FUNCPTR (gst_d3d11_screen_capture_src_create);
}
static void
gst_d3d11_desktop_dup_src_init (GstD3D11DesktopDupSrc * self)
gst_d3d11_screen_capture_src_init (GstD3D11ScreenCaptureSrc * self)
{
gst_base_src_set_live (GST_BASE_SRC (self), TRUE);
gst_base_src_set_format (GST_BASE_SRC (self), GST_FORMAT_TIME);
@ -203,21 +206,21 @@ gst_d3d11_desktop_dup_src_init (GstD3D11DesktopDupSrc * self)
}
static void
gst_d3d11_desktop_dup_src_dispose (GObject * object)
gst_d3d11_screen_capture_src_dispose (GObject * object)
{
GstD3D11DesktopDupSrc *self = GST_D3D11_DESKTOP_DUP_SRC (object);
GstD3D11ScreenCaptureSrc *self = GST_D3D11_SCREEN_CAPTURE_SRC (object);
gst_clear_object (&self->dupl);
gst_clear_object (&self->capture);
gst_clear_object (&self->device);
G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
gst_d3d11_desktop_dup_src_set_property (GObject * object, guint prop_id,
gst_d3d11_screen_capture_src_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstD3D11DesktopDupSrc *self = GST_D3D11_DESKTOP_DUP_SRC (object);
GstD3D11ScreenCaptureSrc *self = GST_D3D11_SCREEN_CAPTURE_SRC (object);
switch (prop_id) {
case PROP_MONITOR_INDEX:
@ -236,10 +239,10 @@ gst_d3d11_desktop_dup_src_set_property (GObject * object, guint prop_id,
}
static void
gst_d3d11_desktop_dup_src_get_property (GObject * object, guint prop_id,
gst_d3d11_screen_capture_src_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstD3D11DesktopDupSrc *self = GST_D3D11_DESKTOP_DUP_SRC (object);
GstD3D11ScreenCaptureSrc *self = GST_D3D11_SCREEN_CAPTURE_SRC (object);
switch (prop_id) {
case PROP_MONITOR_INDEX:
@ -258,10 +261,10 @@ gst_d3d11_desktop_dup_src_get_property (GObject * object, guint prop_id,
}
static void
gst_d3d11_desktop_dup_src_set_context (GstElement * element,
gst_d3d11_screen_capture_src_set_context (GstElement * element,
GstContext * context)
{
GstD3D11DesktopDupSrc *self = GST_D3D11_DESKTOP_DUP_SRC (element);
GstD3D11ScreenCaptureSrc *self = GST_D3D11_SCREEN_CAPTURE_SRC (element);
gst_d3d11_handle_set_context_for_adapter_luid (element,
context, self->adapter_luid, &self->device);
@ -270,18 +273,18 @@ gst_d3d11_desktop_dup_src_set_context (GstElement * element,
}
static GstCaps *
gst_d3d11_desktop_dup_src_get_caps (GstBaseSrc * bsrc, GstCaps * filter)
gst_d3d11_screen_capture_src_get_caps (GstBaseSrc * bsrc, GstCaps * filter)
{
GstD3D11DesktopDupSrc *self = GST_D3D11_DESKTOP_DUP_SRC (bsrc);
GstD3D11ScreenCaptureSrc *self = GST_D3D11_SCREEN_CAPTURE_SRC (bsrc);
GstCaps *caps = NULL;
guint width, height;
if (!self->dupl) {
if (!self->capture) {
GST_DEBUG_OBJECT (self, "Duplication object is not configured yet");
return gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD (bsrc));
}
if (!gst_d3d11_desktop_dup_get_size (self->dupl, &width, &height)) {
if (!gst_d3d11_screen_capture_get_size (self->capture, &width, &height)) {
GST_ELEMENT_ERROR (self, RESOURCE, OPEN_READ,
("Cannot query supported resolution"), (NULL));
return NULL;
@ -305,7 +308,7 @@ gst_d3d11_desktop_dup_src_get_caps (GstBaseSrc * bsrc, GstCaps * filter)
}
static GstCaps *
gst_d3d11_desktop_dup_src_fixate (GstBaseSrc * bsrc, GstCaps * caps)
gst_d3d11_screen_capture_src_fixate (GstBaseSrc * bsrc, GstCaps * caps)
{
guint size;
GstCaps *d3d11_caps = nullptr;
@ -347,9 +350,9 @@ gst_d3d11_desktop_dup_src_fixate (GstBaseSrc * bsrc, GstCaps * caps)
}
static gboolean
gst_d3d11_desktop_dup_src_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
gst_d3d11_screen_capture_src_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
{
GstD3D11DesktopDupSrc *self = GST_D3D11_DESKTOP_DUP_SRC (bsrc);
GstD3D11ScreenCaptureSrc *self = GST_D3D11_SCREEN_CAPTURE_SRC (bsrc);
GstCapsFeatures *features;
GST_DEBUG_OBJECT (self, "Set caps %" GST_PTR_FORMAT, caps);
@ -369,10 +372,10 @@ gst_d3d11_desktop_dup_src_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
}
static gboolean
gst_d3d11_desktop_dup_src_decide_allocation (GstBaseSrc * bsrc,
gst_d3d11_screen_capture_src_decide_allocation (GstBaseSrc * bsrc,
GstQuery * query)
{
GstD3D11DesktopDupSrc *self = GST_D3D11_DESKTOP_DUP_SRC (bsrc);
GstD3D11ScreenCaptureSrc *self = GST_D3D11_SCREEN_CAPTURE_SRC (bsrc);
GstBufferPool *pool = NULL;
GstStructure *config;
GstD3D11AllocationParams *d3d11_params;
@ -501,9 +504,9 @@ error:
}
static gboolean
gst_d3d11_desktop_dup_src_start (GstBaseSrc * bsrc)
gst_d3d11_screen_capture_src_start (GstBaseSrc * bsrc)
{
GstD3D11DesktopDupSrc *self = GST_D3D11_DESKTOP_DUP_SRC (bsrc);
GstD3D11ScreenCaptureSrc *self = GST_D3D11_SCREEN_CAPTURE_SRC (bsrc);
GstFlowReturn ret;
HMONITOR monitor = self->monitor_handle;
ComPtr < IDXGIAdapter1 > adapter;
@ -511,13 +514,13 @@ gst_d3d11_desktop_dup_src_start (GstBaseSrc * bsrc)
HRESULT hr;
if (monitor) {
hr = gst_d3d11_desktop_dup_find_output_for_monitor (monitor,
hr = gst_d3d11_screen_capture_find_output_for_monitor (monitor,
&adapter, nullptr);
} else if (self->monitor_index < 0) {
hr = gst_d3d11_desktop_dup_find_primary_monitor (&monitor,
hr = gst_d3d11_screen_capture_find_primary_monitor (&monitor,
&adapter, nullptr);
} else {
hr = gst_d3d11_desktop_dup_find_nth_monitor (self->monitor_index,
hr = gst_d3d11_screen_capture_find_nth_monitor (self->monitor_index,
&monitor, &adapter, nullptr);
}
@ -540,17 +543,17 @@ gst_d3d11_desktop_dup_src_start (GstBaseSrc * bsrc)
return FALSE;
}
self->dupl = gst_d3d11_desktop_dup_new (self->device, monitor);
if (!self->dupl)
self->capture = gst_d3d11_screen_capture_new (self->device, monitor);
if (!self->capture)
goto error;
/* Check if we can open device */
ret = gst_d3d11_desktop_dup_prepare (self->dupl);
ret = gst_d3d11_screen_capture_prepare (self->capture);
switch (ret) {
case GST_D3D11_DESKTOP_DUP_FLOW_EXPECTED_ERROR:
case GST_D3D11_SCREEN_CAPTURE_FLOW_EXPECTED_ERROR:
case GST_FLOW_OK:
break;
case GST_D3D11_DESKTOP_DUP_FLOW_UNSUPPORTED:
case GST_D3D11_SCREEN_CAPTURE_FLOW_UNSUPPORTED:
goto unsupported;
default:
goto error;
@ -564,7 +567,7 @@ gst_d3d11_desktop_dup_src_start (GstBaseSrc * bsrc)
error:
{
GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND,
("Failed to prepare duplication with given configuration, "
("Failed to prepare capture object with given configuration, "
"monitor-index: %d, monitor-handle: %p",
self->monitor_index, self->monitor_handle), (nullptr));
return FALSE;
@ -573,7 +576,7 @@ error:
unsupported:
{
GST_ELEMENT_ERROR (self, RESOURCE, OPEN_READ,
("Failed to prepare duplication with given configuration, "
("Failed to prepare capture object with given configuration, "
"monitor-index: %d, monitor-handle: %p",
self->monitor_index, self->monitor_handle),
("Try run the application on the integrated GPU"));
@ -582,25 +585,25 @@ unsupported:
}
static gboolean
gst_d3d11_desktop_dup_src_stop (GstBaseSrc * bsrc)
gst_d3d11_screen_capture_src_stop (GstBaseSrc * bsrc)
{
GstD3D11DesktopDupSrc *self = GST_D3D11_DESKTOP_DUP_SRC (bsrc);
GstD3D11ScreenCaptureSrc *self = GST_D3D11_SCREEN_CAPTURE_SRC (bsrc);
if (self->pool) {
gst_buffer_pool_set_active (self->pool, FALSE);
gst_clear_object (&self->pool);
}
gst_clear_object (&self->dupl);
gst_clear_object (&self->capture);
gst_clear_object (&self->device);
return TRUE;
}
static gboolean
gst_d3d11_desktop_dup_src_unlock (GstBaseSrc * bsrc)
gst_d3d11_screen_capture_src_unlock (GstBaseSrc * bsrc)
{
GstD3D11DesktopDupSrc *self = GST_D3D11_DESKTOP_DUP_SRC (bsrc);
GstD3D11ScreenCaptureSrc *self = GST_D3D11_SCREEN_CAPTURE_SRC (bsrc);
GST_OBJECT_LOCK (self);
if (self->clock_id) {
@ -614,9 +617,9 @@ gst_d3d11_desktop_dup_src_unlock (GstBaseSrc * bsrc)
}
static gboolean
gst_d3d11_desktop_dup_src_unlock_stop (GstBaseSrc * bsrc)
gst_d3d11_screen_capture_src_unlock_stop (GstBaseSrc * bsrc)
{
GstD3D11DesktopDupSrc *self = GST_D3D11_DESKTOP_DUP_SRC (bsrc);
GstD3D11ScreenCaptureSrc *self = GST_D3D11_SCREEN_CAPTURE_SRC (bsrc);
GST_OBJECT_LOCK (self);
self->flushing = FALSE;
@ -626,9 +629,9 @@ gst_d3d11_desktop_dup_src_unlock_stop (GstBaseSrc * bsrc)
}
static gboolean
gst_d3d11_desktop_dup_src_src_query (GstBaseSrc * bsrc, GstQuery * query)
gst_d3d11_screen_capture_src_src_query (GstBaseSrc * bsrc, GstQuery * query)
{
GstD3D11DesktopDupSrc *self = GST_D3D11_DESKTOP_DUP_SRC (bsrc);
GstD3D11ScreenCaptureSrc *self = GST_D3D11_SCREEN_CAPTURE_SRC (bsrc);
switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_CONTEXT:
@ -652,10 +655,10 @@ gst_d3d11_desktop_dup_src_src_query (GstBaseSrc * bsrc, GstQuery * query)
}
static GstFlowReturn
gst_d3d11_desktop_dup_src_create (GstBaseSrc * bsrc, guint64 offset, guint size,
GstBuffer ** buf)
gst_d3d11_screen_capture_src_create (GstBaseSrc * bsrc, guint64 offset,
guint size, GstBuffer ** buf)
{
GstD3D11DesktopDupSrc *self = GST_D3D11_DESKTOP_DUP_SRC (bsrc);
GstD3D11ScreenCaptureSrc *self = GST_D3D11_SCREEN_CAPTURE_SRC (bsrc);
ID3D11Texture2D *texture;
ID3D11RenderTargetView *rtv = NULL;
gint fps_n, fps_d;
@ -678,9 +681,9 @@ gst_d3d11_desktop_dup_src_create (GstBaseSrc * bsrc, guint64 offset, guint size,
GstBuffer *buffer = NULL;
GstBuffer *sysmem_buf = NULL;
if (!self->dupl) {
if (!self->capture) {
GST_ELEMENT_ERROR (self, RESOURCE, OPEN_READ,
("Couldn't configure DXGI Desktop Duplication capture object"), (NULL));
("Couldn't configure capture object"), (nullptr));
return GST_FLOW_NOT_NEGOTIATED;
}
@ -694,7 +697,7 @@ again:
clock = gst_element_get_clock (GST_ELEMENT_CAST (self));
if (!clock) {
GST_ELEMENT_ERROR (self, RESOURCE, FAILED,
("Cannot operate without a clock"), (NULL));
("Cannot operate without a clock"), (nullptr));
return GST_FLOW_ERROR;
}
@ -804,15 +807,17 @@ again:
texture = (ID3D11Texture2D *) info.data;
before_capture = gst_clock_get_time (clock);
ret = gst_d3d11_desktop_dup_capture (self->dupl, texture, rtv, draw_mouse);
ret =
gst_d3d11_screen_capture_do_capture (self->capture, texture, rtv,
draw_mouse);
gst_memory_unmap (mem, &info);
switch (ret) {
case GST_D3D11_DESKTOP_DUP_FLOW_EXPECTED_ERROR:
case GST_D3D11_SCREEN_CAPTURE_FLOW_EXPECTED_ERROR:
GST_WARNING_OBJECT (self, "Got expected error, try again");
gst_clear_object (&clock);
goto again;
case GST_D3D11_DESKTOP_DUP_FLOW_UNSUPPORTED:
case GST_D3D11_SCREEN_CAPTURE_FLOW_UNSUPPORTED:
GST_WARNING_OBJECT (self, "Got DXGI_ERROR_UNSUPPORTED error");
unsupported_retry_count--;
@ -821,7 +826,7 @@ again:
gst_clear_object (&clock);
goto again;
case GST_D3D11_DESKTOP_DUP_FLOW_SIZE_CHANGED:
case GST_D3D11_SCREEN_CAPTURE_FLOW_SIZE_CHANGED:
GST_INFO_OBJECT (self, "Size was changed, need negotiation");
gst_clear_buffer (&buffer);
gst_clear_object (&clock);

View file

@ -18,8 +18,7 @@
* Boston, MA 02110-1301, USA.
*/
#ifndef __GST_D3D11_DESKTOP_DUP_SRC_H__
#define __GST_D3D11_DESKTOP_DUP_SRC_H__
#pragma once
#include <gst/gst.h>
#include <gst/video/video.h>
@ -28,10 +27,9 @@
G_BEGIN_DECLS
#define GST_TYPE_D3D11_DESKTOP_DUP_SRC (gst_d3d11_desktop_dup_src_get_type())
G_DECLARE_FINAL_TYPE (GstD3D11DesktopDupSrc, gst_d3d11_desktop_dup_src,
GST, D3D11_DESKTOP_DUP_SRC, GstBaseSrc);
#define GST_TYPE_D3D11_SCREEN_CAPTURE_SRC (gst_d3d11_screen_capture_src_get_type())
G_DECLARE_FINAL_TYPE (GstD3D11ScreenCaptureSrc, gst_d3d11_screen_capture_src,
GST, D3D11_SCREEN_CAPTURE_SRC, GstBaseSrc);
G_END_DECLS
#endif /* __GST_D3D11_DESKTOP_DUP_H__ */

View file

@ -84,9 +84,9 @@ if d3d11_winapi_desktop
# Desktop Duplication API is unavailable for UWP
# and MinGW is not supported due to some missing headers
extra_args += ['-DHAVE_DXGI_DESKTOP_DUP']
d3d11_sources += ['gstd3d11desktopdup.cpp',
'gstd3d11desktopdupdevice.cpp',
'gstd3d11desktopdupsrc.cpp']
d3d11_sources += ['gstd3d11screencapture.cpp',
'gstd3d11screencapturedevice.cpp',
'gstd3d11screencapturesrc.cpp']
message('Enable D3D11 Desktop Duplication API')
endif
# multimedia clock is desktop only API

View file

@ -39,8 +39,8 @@
#include "gstd3d11av1dec.h"
#endif
#ifdef HAVE_DXGI_DESKTOP_DUP
#include "gstd3d11desktopdupsrc.h"
#include "gstd3d11desktopdupdevice.h"
#include "gstd3d11screencapturesrc.h"
#include "gstd3d11screencapturedevice.h"
#endif
#ifdef HAVE_D3D11_VIDEO_PROC
#include "gstd3d11deinterlace.h"
@ -68,8 +68,8 @@ GST_DEBUG_CATEGORY (gst_d3d11_av1_dec_debug);
#endif
#ifdef HAVE_DXGI_DESKTOP_DUP
GST_DEBUG_CATEGORY (gst_d3d11_desktop_dup_debug);
GST_DEBUG_CATEGORY (gst_d3d11_desktop_dup_device_debug);
GST_DEBUG_CATEGORY (gst_d3d11_screen_capture_debug);
GST_DEBUG_CATEGORY (gst_d3d11_screen_capture_device_debug);
#endif
#ifdef HAVE_D3D11_VIDEO_PROC
@ -213,16 +213,17 @@ plugin_init (GstPlugin * plugin)
#ifdef HAVE_DXGI_DESKTOP_DUP
if (gst_d3d11_is_windows_8_or_greater ()) {
GST_DEBUG_CATEGORY_INIT (gst_d3d11_desktop_dup_debug,
"d3d11desktopdupsrc", 0, "d3d11desktopdupsrc");
GST_DEBUG_CATEGORY_INIT (gst_d3d11_desktop_dup_device_debug,
"d3d11desktopdupdevice", 0, "d3d11desktopdupdevice");
GST_DEBUG_CATEGORY_INIT (gst_d3d11_screen_capture_debug,
"d3d11screencapturesrc", 0, "d3d11screencapturesrc");
GST_DEBUG_CATEGORY_INIT (gst_d3d11_screen_capture_device_debug,
"d3d11screencapturedevice", 0, "d3d11screencapturedevice");
gst_element_register (plugin,
"d3d11desktopdupsrc", GST_RANK_NONE, GST_TYPE_D3D11_DESKTOP_DUP_SRC);
"d3d11screencapturesrc", GST_RANK_NONE,
GST_TYPE_D3D11_SCREEN_CAPTURE_SRC);
gst_device_provider_register (plugin,
"d3d11desktopdupdeviceprovider", GST_RANK_PRIMARY,
GST_TYPE_D3D11_DESKTOP_DUP_DEVICE_PROVIDER);
"d3d11screencapturedeviceprovider", GST_RANK_PRIMARY,
GST_TYPE_D3D11_SCREEN_CAPTURE_DEVICE_PROVIDER);
}
#endif

View file

@ -161,7 +161,7 @@ main (gint argc, gchar ** argv)
{nullptr}
};
option_ctx = g_option_context_new ("D3D11 desktop capture example");
option_ctx = g_option_context_new ("D3D11 screen capture example");
g_option_context_add_main_entries (option_ctx, options, NULL);
g_option_context_add_group (option_ctx, gst_init_get_option_group ());
ret = g_option_context_parse (option_ctx, &argc, &argv, &err);
@ -187,7 +187,7 @@ main (gint argc, gchar ** argv)
src = gst_device_create_element (device, nullptr);
gst_object_unref (device);
if (!src) {
g_warning ("Failed to create d3d11desktopdup element");
g_warning ("Failed to create d3d11screencapture element");
return 1;
}

View file

@ -7,8 +7,8 @@ if host_system == 'windows'
install: false,
)
executable('d3d11desktopdupsrc',
['d3d11desktopdupsrc.cpp'],
executable('d3d11screencapturesrc',
['d3d11screencapturesrc.cpp'],
c_args : gst_plugins_bad_args,
include_directories : [configinc, libsinc],
dependencies: [gst_dep, gstbase_dep, gstvideo_dep],