mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-17 21:06:17 +00:00
d3d11ipc: Use unnamed shareable handle
Exchanging HANDLE would have smaller overhead than string Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4774>
This commit is contained in:
parent
1e5343f0c6
commit
ef1853aa8d
6 changed files with 139 additions and 232 deletions
|
@ -49,7 +49,7 @@ gst_d3d11_ipc_pkt_identify (std::vector < guint8 > &buf,
|
|||
|
||||
bool
|
||||
gst_d3d11_ipc_pkt_build_config (std::vector < guint8 > &buf,
|
||||
gint64 adapter_luid, GstCaps * caps)
|
||||
DWORD pid, gint64 adapter_luid, GstCaps * caps)
|
||||
{
|
||||
GstD3D11IpcPacketHeader header;
|
||||
guint8 *ptr;
|
||||
|
@ -66,7 +66,7 @@ gst_d3d11_ipc_pkt_build_config (std::vector < guint8 > &buf,
|
|||
|
||||
header.type = GstD3D11IpcPktType::CONFIG;
|
||||
header.magic = GST_D3D11_IPC_MAGIC_NUMBER;
|
||||
header.payload_size = sizeof (gint64) + caps_size;
|
||||
header.payload_size = sizeof (DWORD) + sizeof (gint64) + caps_size;
|
||||
|
||||
buf.resize (GST_D3D11_IPC_PKT_HEADER_SIZE + header.payload_size);
|
||||
|
||||
|
@ -75,6 +75,9 @@ gst_d3d11_ipc_pkt_build_config (std::vector < guint8 > &buf,
|
|||
memcpy (ptr, &header, GST_D3D11_IPC_PKT_HEADER_SIZE);
|
||||
ptr += GST_D3D11_IPC_PKT_HEADER_SIZE;
|
||||
|
||||
memcpy (ptr, &pid, sizeof (DWORD));
|
||||
ptr += sizeof (DWORD);
|
||||
|
||||
memcpy (ptr, &adapter_luid, sizeof (gint64));
|
||||
ptr += sizeof (gint64);
|
||||
|
||||
|
@ -86,7 +89,7 @@ gst_d3d11_ipc_pkt_build_config (std::vector < guint8 > &buf,
|
|||
|
||||
bool
|
||||
gst_d3d11_ipc_pkt_parse_config (std::vector < guint8 > &buf,
|
||||
gint64 & adapter_luid, GstCaps ** caps)
|
||||
DWORD & pid, gint64 & adapter_luid, GstCaps ** caps)
|
||||
{
|
||||
GstD3D11IpcPacketHeader header;
|
||||
const guint8 *ptr;
|
||||
|
@ -107,6 +110,9 @@ gst_d3d11_ipc_pkt_parse_config (std::vector < guint8 > &buf,
|
|||
|
||||
ptr += GST_D3D11_IPC_PKT_HEADER_SIZE;
|
||||
|
||||
memcpy (&pid, ptr, sizeof (DWORD));
|
||||
ptr += sizeof (DWORD);
|
||||
|
||||
memcpy (&adapter_luid, ptr, sizeof (gint64));
|
||||
ptr += sizeof (gint64);
|
||||
|
||||
|
@ -135,28 +141,25 @@ gst_d3d11_ipc_pkt_build_need_data (std::vector < guint8 > &buf)
|
|||
bool
|
||||
gst_d3d11_ipc_pkt_build_have_data (std::vector < guint8 > &buf,
|
||||
GstClockTime pts, const GstD3D11IpcMemLayout & layout,
|
||||
const std::wstring & name, GstCaps * caps)
|
||||
const HANDLE handle, GstCaps * caps)
|
||||
{
|
||||
GstD3D11IpcPacketHeader header;
|
||||
guint8 *ptr;
|
||||
guint name_size;
|
||||
gchar *caps_str = nullptr;
|
||||
guint caps_size = 1;
|
||||
|
||||
name_size = (name.length () + 1) * sizeof (wchar_t);
|
||||
|
||||
if (caps) {
|
||||
caps_str = gst_caps_serialize (caps, GST_SERIALIZE_FLAG_NONE);
|
||||
if (!caps_str)
|
||||
return false;
|
||||
|
||||
caps_size = strlen (caps_str) + 1;
|
||||
caps_size += strlen (caps_str) + 1;
|
||||
}
|
||||
|
||||
header.type = GstD3D11IpcPktType::HAVE_DATA;
|
||||
header.magic = GST_D3D11_IPC_MAGIC_NUMBER;
|
||||
header.payload_size = sizeof (GstClockTime) + sizeof (GstD3D11IpcMemLayout) +
|
||||
name_size + caps_size;
|
||||
sizeof (HANDLE) + caps_size;
|
||||
|
||||
buf.resize (GST_D3D11_IPC_PKT_HEADER_SIZE + header.payload_size);
|
||||
|
||||
|
@ -170,8 +173,8 @@ gst_d3d11_ipc_pkt_build_have_data (std::vector < guint8 > &buf,
|
|||
memcpy (ptr, &layout, sizeof (GstD3D11IpcMemLayout));
|
||||
ptr += sizeof (GstD3D11IpcMemLayout);
|
||||
|
||||
wcscpy ((wchar_t *) ptr, name.c_str ());
|
||||
ptr += name_size;
|
||||
memcpy (ptr, &handle, sizeof (HANDLE));
|
||||
ptr += sizeof (HANDLE);
|
||||
|
||||
if (caps) {
|
||||
*ptr = 1;
|
||||
|
@ -191,7 +194,7 @@ gst_d3d11_ipc_pkt_build_have_data (std::vector < guint8 > &buf,
|
|||
bool
|
||||
gst_d3d11_ipc_pkt_parse_have_data (const std::vector < guint8 > &buf,
|
||||
GstClockTime & pts, GstD3D11IpcMemLayout & layout,
|
||||
std::wstring & name, GstCaps ** caps)
|
||||
HANDLE & handle, GstCaps ** caps)
|
||||
{
|
||||
GstD3D11IpcPacketHeader header;
|
||||
const guint8 *ptr;
|
||||
|
@ -219,9 +222,8 @@ gst_d3d11_ipc_pkt_parse_have_data (const std::vector < guint8 > &buf,
|
|||
memcpy (&layout, ptr, sizeof (GstD3D11IpcMemLayout));
|
||||
ptr += sizeof (GstD3D11IpcMemLayout);
|
||||
|
||||
name = (wchar_t *) ptr;
|
||||
|
||||
ptr += (name.size () + 1) * sizeof (wchar_t);
|
||||
memcpy (&handle, ptr, sizeof (HANDLE));
|
||||
ptr += sizeof (HANDLE);
|
||||
|
||||
if (*ptr) {
|
||||
ptr++;
|
||||
|
@ -250,14 +252,14 @@ gst_d3d11_ipc_pkt_build_read_done (std::vector < guint8 > &buf)
|
|||
|
||||
void
|
||||
gst_d3d11_ipc_pkt_build_release_data (std::vector < guint8 > &buf,
|
||||
const std::wstring & name)
|
||||
const HANDLE handle)
|
||||
{
|
||||
GstD3D11IpcPacketHeader header;
|
||||
guint8 *ptr;
|
||||
|
||||
header.type = GstD3D11IpcPktType::RELEASE_DATA;
|
||||
header.magic = GST_D3D11_IPC_MAGIC_NUMBER;
|
||||
header.payload_size = (name.size () + 1) * sizeof (wchar_t);
|
||||
header.payload_size = sizeof (HANDLE);
|
||||
|
||||
buf.resize (GST_D3D11_IPC_PKT_HEADER_SIZE + header.payload_size);
|
||||
|
||||
|
@ -265,16 +267,30 @@ gst_d3d11_ipc_pkt_build_release_data (std::vector < guint8 > &buf,
|
|||
memcpy (ptr, &header, GST_D3D11_IPC_PKT_HEADER_SIZE);
|
||||
ptr += GST_D3D11_IPC_PKT_HEADER_SIZE;
|
||||
|
||||
wcscpy ((wchar_t *) ptr, name.c_str ());
|
||||
memcpy (ptr, &handle, sizeof (HANDLE));
|
||||
}
|
||||
|
||||
bool
|
||||
gst_d3d11_ipc_pkt_parse_release_data (std::vector < guint8 > &buf,
|
||||
std::wstring & name)
|
||||
HANDLE & handle)
|
||||
{
|
||||
g_return_val_if_fail (buf.size () > GST_D3D11_IPC_PKT_HEADER_SIZE, false);
|
||||
GstD3D11IpcPacketHeader header;
|
||||
const guint8 *ptr;
|
||||
|
||||
name = (wchar_t *) (&buf[0] + GST_D3D11_IPC_PKT_HEADER_SIZE);
|
||||
g_return_val_if_fail (buf.size () >=
|
||||
GST_D3D11_IPC_PKT_HEADER_SIZE + sizeof (HANDLE), false);
|
||||
|
||||
ptr = &buf[0];
|
||||
memcpy (&header, ptr, GST_D3D11_IPC_PKT_HEADER_SIZE);
|
||||
|
||||
if (header.type != GstD3D11IpcPktType::RELEASE_DATA ||
|
||||
header.magic != GST_D3D11_IPC_MAGIC_NUMBER ||
|
||||
header.payload_size != sizeof (HANDLE)) {
|
||||
return false;
|
||||
}
|
||||
ptr += GST_D3D11_IPC_PKT_HEADER_SIZE;
|
||||
|
||||
memcpy (&handle, ptr, sizeof (HANDLE));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -380,40 +396,3 @@ gst_d3d11_ipc_win32_error_to_string (guint err)
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gint64
|
||||
gst_d3d11_ipc_get_shared_resource_token (void)
|
||||
{
|
||||
static gint64 token = 0;
|
||||
|
||||
GST_D3D11_CALL_ONCE_BEGIN {
|
||||
token = gst_d3d11_create_user_token ();
|
||||
} GST_D3D11_CALL_ONCE_END;
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
static DWORD
|
||||
gst_d3d11_ipc_get_pid (void)
|
||||
{
|
||||
static DWORD pid = 0;
|
||||
|
||||
GST_D3D11_CALL_ONCE_BEGIN {
|
||||
pid = GetCurrentProcessId ();
|
||||
} GST_D3D11_CALL_ONCE_END;
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
std::wstring
|
||||
gst_d3d11_ipc_get_resource_prefix (void)
|
||||
{
|
||||
static ULONG global_index = 0;
|
||||
|
||||
std::wstring prefix = std::wstring (L"Local\\gst.d3d11.ipc.") +
|
||||
std::to_wstring (gst_d3d11_ipc_get_pid ()) + std::wstring (L".") +
|
||||
std::to_wstring (InterlockedIncrement (&global_index)) +
|
||||
std::wstring (L".");
|
||||
|
||||
return prefix;
|
||||
}
|
||||
|
|
|
@ -91,18 +91,6 @@ struct GstD3D11IpcMemLayout
|
|||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
struct GstD3D11IpcHandleData
|
||||
{
|
||||
~GstD3D11IpcHandleData ()
|
||||
{
|
||||
if (handle)
|
||||
CloseHandle (handle);
|
||||
}
|
||||
|
||||
HANDLE handle = nullptr;
|
||||
std::wstring name;
|
||||
};
|
||||
|
||||
constexpr guint GST_D3D11_IPC_PKT_HEADER_SIZE = sizeof (GstD3D11IpcPacketHeader);
|
||||
|
||||
#define GST_D3D11_IPC_FORMATS \
|
||||
|
@ -113,10 +101,12 @@ bool gst_d3d11_ipc_pkt_identify (std::vector<guint8> & buf,
|
|||
GstD3D11IpcPacketHeader & header);
|
||||
|
||||
bool gst_d3d11_ipc_pkt_build_config (std::vector<guint8> & buf,
|
||||
DWORD pid,
|
||||
gint64 adapter_luid,
|
||||
GstCaps * caps);
|
||||
|
||||
bool gst_d3d11_ipc_pkt_parse_config (std::vector<guint8> & buf,
|
||||
DWORD & pid,
|
||||
gint64 & adapter_luid,
|
||||
GstCaps ** caps);
|
||||
|
||||
|
@ -125,22 +115,22 @@ void gst_d3d11_ipc_pkt_build_need_data (std::vector<guint8> & buf);
|
|||
bool gst_d3d11_ipc_pkt_build_have_data (std::vector<guint8> & buf,
|
||||
GstClockTime pts,
|
||||
const GstD3D11IpcMemLayout & layout,
|
||||
const std::wstring & name,
|
||||
const HANDLE handle,
|
||||
GstCaps * caps);
|
||||
|
||||
bool gst_d3d11_ipc_pkt_parse_have_data (const std::vector<guint8> & buf,
|
||||
GstClockTime & pts,
|
||||
GstD3D11IpcMemLayout & layout,
|
||||
std::wstring & name,
|
||||
HANDLE & handle,
|
||||
GstCaps ** caps);
|
||||
|
||||
void gst_d3d11_ipc_pkt_build_read_done (std::vector<guint8> & buf);
|
||||
|
||||
void gst_d3d11_ipc_pkt_build_release_data (std::vector<guint8> & buf,
|
||||
const std::wstring & name);
|
||||
const HANDLE handle);
|
||||
|
||||
bool gst_d3d11_ipc_pkt_parse_release_data (std::vector<guint8> & buf,
|
||||
std::wstring & name);
|
||||
HANDLE & handle);
|
||||
|
||||
void gst_d3d11_ipc_pkt_build_eos (std::vector<guint8> & buf);
|
||||
|
||||
|
@ -156,6 +146,3 @@ std::wstring gst_d3d11_ipc_string_to_wstring (const std::string & str);
|
|||
|
||||
std::string gst_d3d11_ipc_win32_error_to_string (guint err);
|
||||
|
||||
gint64 gst_d3d11_ipc_get_shared_resource_token (void);
|
||||
|
||||
std::wstring gst_d3d11_ipc_get_resource_prefix (void);
|
||||
|
|
|
@ -91,8 +91,7 @@ struct GstD3D11IpcImportData
|
|||
{
|
||||
~GstD3D11IpcImportData ()
|
||||
{
|
||||
auto dump = gst_d3d11_ipc_wstring_to_string (name);
|
||||
GST_LOG_OBJECT (client, "Release handle \"%s\"", dump.c_str ());
|
||||
GST_LOG_OBJECT (client, "Release handle \"%p\"", server_handle);
|
||||
gst_object_unref (client);
|
||||
}
|
||||
|
||||
|
@ -100,7 +99,7 @@ struct GstD3D11IpcImportData
|
|||
ComPtr<ID3D11Texture2D> texture;
|
||||
ComPtr<IDXGIKeyedMutex> mutex;
|
||||
GstD3D11IpcMemLayout layout;
|
||||
std::wstring name;
|
||||
HANDLE server_handle = nullptr;
|
||||
};
|
||||
|
||||
struct GstD3D11IpcReleaseData
|
||||
|
@ -132,6 +131,8 @@ struct GstD3D11IpcClientPrivate
|
|||
|
||||
CloseHandle (wakeup_event);
|
||||
CloseHandle (cancellable);
|
||||
if (server_process)
|
||||
CloseHandle (server_process);
|
||||
}
|
||||
|
||||
std::string address;
|
||||
|
@ -139,6 +140,7 @@ struct GstD3D11IpcClientPrivate
|
|||
GstClockTime timeout;
|
||||
HANDLE wakeup_event;
|
||||
HANDLE cancellable;
|
||||
HANDLE server_process = nullptr;
|
||||
std::mutex lock;
|
||||
std::condition_variable cond;
|
||||
GstD3D11Device *device = nullptr;
|
||||
|
@ -154,7 +156,7 @@ struct GstD3D11IpcClientPrivate
|
|||
GThread *loop_thread = nullptr;
|
||||
std::queue <GstSample *> samples;
|
||||
std::shared_ptr<GstD3D11IpcClientConn> conn;
|
||||
std::queue<std::wstring> unused_data;
|
||||
std::queue<HANDLE> unused_data;
|
||||
std::vector<std::weak_ptr<GstD3D11IpcImportData>> imported;
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
@ -309,15 +311,31 @@ gst_d3d11_ipc_client_config_data (GstD3D11IpcClient * self)
|
|||
gint64 prev_luid, luid;
|
||||
GstCaps *caps = nullptr;
|
||||
auto conn = priv->conn;
|
||||
DWORD server_pid;
|
||||
std::lock_guard < std::mutex > lk (priv->lock);
|
||||
|
||||
g_object_get (priv->device, "adapter-luid", &prev_luid, nullptr);
|
||||
|
||||
if (!gst_d3d11_ipc_pkt_parse_config (conn->server_msg, luid, &caps)) {
|
||||
if (!gst_d3d11_ipc_pkt_parse_config (conn->server_msg,
|
||||
server_pid, luid, &caps)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't parse CONFIG-DATA");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (priv->server_process) {
|
||||
GST_WARNING_OBJECT (self, "Have server process handle already");
|
||||
CloseHandle (priv->server_process);
|
||||
}
|
||||
|
||||
priv->server_process = OpenProcess (PROCESS_DUP_HANDLE, FALSE, server_pid);
|
||||
if (!priv->server_process) {
|
||||
guint last_err = GetLastError ();
|
||||
auto err = gst_d3d11_ipc_win32_error_to_string (last_err);
|
||||
GST_ERROR_OBJECT (self, "Couldn't open server process, 0x%x (%s)",
|
||||
last_err, err.c_str ());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (prev_luid != luid) {
|
||||
GstD3D11Device *device = gst_d3d11_device_new_for_adapter_luid (luid,
|
||||
D3D11_CREATE_DEVICE_BGRA_SUPPORT);
|
||||
|
@ -343,15 +361,14 @@ gst_d3d11_ipc_client_release_imported_data (GstD3D11IpcReleaseData * data)
|
|||
{
|
||||
GstD3D11IpcClient *self = data->self;
|
||||
GstD3D11IpcClientPrivate *priv = self->priv;
|
||||
auto name = data->imported->name;
|
||||
auto handle_dump = gst_d3d11_ipc_wstring_to_string (name);
|
||||
HANDLE server_handle = data->imported->server_handle;
|
||||
|
||||
GST_LOG_OBJECT (self, "Releasing data \"%s\"", handle_dump.c_str ());
|
||||
GST_LOG_OBJECT (self, "Releasing data \"%p\"", server_handle);
|
||||
|
||||
data->imported = nullptr;
|
||||
|
||||
priv->lock.lock ();
|
||||
priv->unused_data.push (name);
|
||||
priv->unused_data.push (server_handle);
|
||||
priv->lock.unlock ();
|
||||
|
||||
SetEvent (priv->wakeup_event);
|
||||
|
@ -373,13 +390,14 @@ gst_d3d11_ipc_client_have_data (GstD3D11IpcClient * self)
|
|||
GstD3D11IpcMemLayout layout;
|
||||
std::shared_ptr < GstD3D11IpcImportData > import_data;
|
||||
std::unique_lock < std::mutex > lk (priv->lock);
|
||||
std::wstring name;
|
||||
HANDLE server_handle = nullptr;
|
||||
HANDLE client_handle = nullptr;
|
||||
auto conn = priv->conn;
|
||||
ComPtr < ID3D11Texture2D > texture;
|
||||
HRESULT hr;
|
||||
|
||||
if (!gst_d3d11_ipc_pkt_parse_have_data (conn->server_msg,
|
||||
pts, layout, name, &caps)) {
|
||||
pts, layout, server_handle, &caps)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't parse HAVE-DATA packet");
|
||||
return false;
|
||||
}
|
||||
|
@ -387,68 +405,49 @@ gst_d3d11_ipc_client_have_data (GstD3D11IpcClient * self)
|
|||
if (!gst_d3d11_client_update_caps (self, caps))
|
||||
return false;
|
||||
|
||||
auto handle_dump = gst_d3d11_ipc_wstring_to_string (name);
|
||||
GST_LOG_OBJECT (self, "Importing handle \"%s\"", handle_dump.c_str ());
|
||||
|
||||
/* Check if this memory handle was imported already */
|
||||
/* *INDENT-OFF* */
|
||||
if (priv->io_mode == GST_D3D11_IPC_IO_IMPORT && !priv->imported.empty ()) {
|
||||
GST_LOG_OBJECT (self, "Checking already imported handles, size %"
|
||||
G_GSIZE_FORMAT, priv->imported.size ());
|
||||
for (auto it = priv->imported.begin (); it != priv->imported.end (); ) {
|
||||
auto data = it->lock ();
|
||||
if (!data) {
|
||||
it = priv->imported.erase (it);
|
||||
} else {
|
||||
if (data->name == name) {
|
||||
GST_DEBUG_OBJECT (self, "Already imported handle");
|
||||
import_data = data;
|
||||
break;
|
||||
}
|
||||
|
||||
it++;
|
||||
}
|
||||
}
|
||||
if (!DuplicateHandle (priv->server_process, server_handle,
|
||||
GetCurrentProcess (), &client_handle, 0, FALSE,
|
||||
DUPLICATE_SAME_ACCESS)) {
|
||||
guint last_err = GetLastError ();
|
||||
auto err = gst_d3d11_ipc_win32_error_to_string (last_err);
|
||||
GST_ERROR_OBJECT (self, "Couldn't duplicate handle, 0x%x (%s)",
|
||||
last_err, err.c_str ());
|
||||
return false;
|
||||
}
|
||||
/* *INDENT-ON* */
|
||||
|
||||
if (!import_data) {
|
||||
ID3D11Device *device = gst_d3d11_device_get_device_handle (priv->device);
|
||||
ComPtr < ID3D11Device1 > device1;
|
||||
ComPtr < IDXGIKeyedMutex > mutex;
|
||||
GST_LOG_OBJECT (self, "Importing server handle %p", server_handle);
|
||||
|
||||
hr = device->QueryInterface (IID_PPV_ARGS (&device1));
|
||||
if (!gst_d3d11_result (hr, priv->device)) {
|
||||
GST_ERROR_OBJECT (self, "ID3D11Device1 interface is not available");
|
||||
return false;
|
||||
}
|
||||
ID3D11Device *device = gst_d3d11_device_get_device_handle (priv->device);
|
||||
ComPtr < ID3D11Device1 > device1;
|
||||
ComPtr < IDXGIKeyedMutex > mutex;
|
||||
|
||||
hr = device1->OpenSharedResourceByName (name.c_str (),
|
||||
DXGI_SHARED_RESOURCE_READ, IID_PPV_ARGS (&texture));
|
||||
if (!gst_d3d11_result (hr, priv->device)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't open resource");
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = texture->QueryInterface (IID_PPV_ARGS (&mutex));
|
||||
if (!gst_d3d11_result (hr, priv->device)) {
|
||||
GST_ERROR_OBJECT (self, "couldn't get keyed mutex interface");
|
||||
return false;
|
||||
}
|
||||
|
||||
import_data = std::make_shared < GstD3D11IpcImportData > ();
|
||||
import_data->client = (GstD3D11IpcClient *) gst_object_ref (self);
|
||||
import_data->texture = texture;
|
||||
import_data->mutex = mutex;
|
||||
import_data->layout = layout;
|
||||
import_data->name = name;
|
||||
|
||||
if (priv->io_mode == GST_D3D11_IPC_IO_IMPORT)
|
||||
priv->imported.push_back (import_data);
|
||||
} else {
|
||||
texture = import_data->texture;
|
||||
hr = device->QueryInterface (IID_PPV_ARGS (&device1));
|
||||
if (!gst_d3d11_result (hr, priv->device)) {
|
||||
GST_ERROR_OBJECT (self, "ID3D11Device1 interface is not available");
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = device1->OpenSharedResource1 (client_handle, IID_PPV_ARGS (&texture));
|
||||
CloseHandle (client_handle);
|
||||
|
||||
if (!gst_d3d11_result (hr, priv->device)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't open resource");
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = texture->QueryInterface (IID_PPV_ARGS (&mutex));
|
||||
if (!gst_d3d11_result (hr, priv->device)) {
|
||||
GST_ERROR_OBJECT (self, "couldn't get keyed mutex interface");
|
||||
return false;
|
||||
}
|
||||
|
||||
import_data = std::make_shared < GstD3D11IpcImportData > ();
|
||||
import_data->client = (GstD3D11IpcClient *) gst_object_ref (self);
|
||||
import_data->texture = texture;
|
||||
import_data->mutex = mutex;
|
||||
import_data->layout = layout;
|
||||
import_data->server_handle = server_handle;
|
||||
|
||||
if (priv->io_mode == GST_D3D11_IPC_IO_COPY) {
|
||||
ID3D11DeviceContext *context =
|
||||
gst_d3d11_device_get_device_context_handle (priv->device);
|
||||
|
@ -487,7 +486,7 @@ gst_d3d11_ipc_client_have_data (GstD3D11IpcClient * self)
|
|||
|
||||
gst_memory_unmap (mem, &info);
|
||||
|
||||
priv->unused_data.push (name);
|
||||
priv->unused_data.push (server_handle);
|
||||
} else {
|
||||
GstMemory *mem;
|
||||
gint stride[GST_VIDEO_MAX_PLANES];
|
||||
|
@ -514,6 +513,8 @@ gst_d3d11_ipc_client_have_data (GstD3D11IpcClient * self)
|
|||
GST_VIDEO_INFO_FORMAT (&priv->info), GST_VIDEO_INFO_WIDTH (&priv->info),
|
||||
GST_VIDEO_INFO_HEIGHT (&priv->info),
|
||||
GST_VIDEO_INFO_N_PLANES (&priv->info), offset, stride);
|
||||
|
||||
priv->imported.push_back (import_data);
|
||||
}
|
||||
|
||||
GST_BUFFER_PTS (buffer) = pts;
|
||||
|
@ -770,13 +771,12 @@ gst_d3d11_ipc_client_continue (GstD3D11IpcClient * self)
|
|||
}
|
||||
|
||||
if (!priv->unused_data.empty ()) {
|
||||
auto name = priv->unused_data.front ();
|
||||
HANDLE server_handle = priv->unused_data.front ();
|
||||
priv->unused_data.pop ();
|
||||
|
||||
auto handle_dump = gst_d3d11_ipc_wstring_to_string (name);
|
||||
GST_LOG_OBJECT (self, "Sending RELEASE-DATA \"%s\"", handle_dump.c_str ());
|
||||
GST_LOG_OBJECT (self, "Sending RELEASE-DATA %p", server_handle);
|
||||
|
||||
gst_d3d11_ipc_pkt_build_release_data (conn->client_msg, name);
|
||||
gst_d3d11_ipc_pkt_build_release_data (conn->client_msg, server_handle);
|
||||
conn->type = GstD3D11IpcPktType::RELEASE_DATA;
|
||||
lk.unlock ();
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ struct GstD3D11IpcServerData
|
|||
}
|
||||
|
||||
GstSample *sample = nullptr;
|
||||
std::wstring name;
|
||||
HANDLE handle = nullptr;
|
||||
GstD3D11IpcMemLayout layout;
|
||||
GstClockTime pts;
|
||||
guint64 seq_num;
|
||||
|
@ -120,6 +120,7 @@ struct GstD3D11IpcServerPrivate
|
|||
std::string address;
|
||||
HANDLE cancellable;
|
||||
HANDLE wakeup_event;
|
||||
DWORD pid;
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
|
@ -157,6 +158,7 @@ static void
|
|||
gst_d3d11_ipc_server_init (GstD3D11IpcServer * self)
|
||||
{
|
||||
self->priv = new GstD3D11IpcServerPrivate ();
|
||||
self->priv->pid = GetCurrentProcessId ();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -275,12 +277,11 @@ gst_d3d11_ipc_server_have_data (GstD3D11IpcServer * self,
|
|||
caps = nullptr;
|
||||
}
|
||||
|
||||
auto handle_dump = gst_d3d11_ipc_wstring_to_string (conn->data->name);
|
||||
GST_LOG_OBJECT (self, "Sending HAVE-DATA with handle \"%s\", conn-id :%u",
|
||||
handle_dump.c_str (), conn->id);
|
||||
GST_LOG_OBJECT (self, "Sending HAVE-DATA with handle \"%p\", conn-id :%u",
|
||||
conn->data->handle, conn->id);
|
||||
|
||||
if (!gst_d3d11_ipc_pkt_build_have_data (conn->server_msg, conn->data->pts,
|
||||
conn->data->layout, conn->data->name, caps)) {
|
||||
conn->data->layout, conn->data->handle, caps)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't build HAVE-DATA pkt, conn-id: %u",
|
||||
conn->id);
|
||||
gst_d3d11_ipc_server_close_connection (self, conn);
|
||||
|
@ -295,23 +296,21 @@ static bool
|
|||
gst_d3d11_ipc_server_on_release_data (GstD3D11IpcServer * self,
|
||||
GstD3D11IpcServerConn * conn)
|
||||
{
|
||||
std::wstring name;
|
||||
bool found = false;
|
||||
HANDLE handle = nullptr;
|
||||
|
||||
if (!gst_d3d11_ipc_pkt_parse_release_data (conn->client_msg, name)) {
|
||||
if (!gst_d3d11_ipc_pkt_parse_release_data (conn->client_msg, handle)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't parse RELEASE-DATA, conn-id: %u",
|
||||
conn->id);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto handle_dump = gst_d3d11_ipc_wstring_to_string (name);
|
||||
GST_LOG_OBJECT (self, "RELEASE-DATA \"%s\", conn-id: %u",
|
||||
handle_dump.c_str (), conn->id);
|
||||
GST_LOG_OBJECT (self, "RELEASE-DATA \"%p\", conn-id: %u", handle, conn->id);
|
||||
|
||||
for (auto it = conn->peer_handles.begin (); it != conn->peer_handles.end ();
|
||||
it++) {
|
||||
auto other = (*it)->name;
|
||||
if (name == other) {
|
||||
auto other = (*it)->handle;
|
||||
if (handle == other) {
|
||||
found = true;
|
||||
conn->peer_handles.erase (it);
|
||||
break;
|
||||
|
@ -481,8 +480,8 @@ gst_d3d11_ipc_server_config_data (GstD3D11IpcServer * self,
|
|||
|
||||
gst_caps_replace (&conn->caps, caps);
|
||||
|
||||
gst_d3d11_ipc_pkt_build_config (conn->server_msg, priv->adapter_luid,
|
||||
conn->caps);
|
||||
gst_d3d11_ipc_pkt_build_config (conn->server_msg,
|
||||
priv->pid, priv->adapter_luid, conn->caps);
|
||||
conn->type = GstD3D11IpcPktType::CONFIG;
|
||||
|
||||
GST_LOG_OBJECT (self, "Sending CONFIG, conn-id %u", conn->id);
|
||||
|
@ -744,8 +743,7 @@ out:
|
|||
|
||||
GstFlowReturn
|
||||
gst_d3d11_ipc_server_send_data (GstD3D11IpcServer * server, GstSample * sample,
|
||||
const GstD3D11IpcMemLayout & layout, const std::wstring & name,
|
||||
GstClockTime pts)
|
||||
const GstD3D11IpcMemLayout & layout, HANDLE handle, GstClockTime pts)
|
||||
{
|
||||
GstD3D11IpcServerPrivate *priv;
|
||||
|
||||
|
@ -764,7 +762,7 @@ gst_d3d11_ipc_server_send_data (GstD3D11IpcServer * server, GstSample * sample,
|
|||
|
||||
auto data = std::make_shared < GstD3D11IpcServerData > ();
|
||||
data->sample = gst_sample_ref (sample);
|
||||
data->name = name;
|
||||
data->handle = handle;
|
||||
data->layout = layout;
|
||||
data->pts = pts;
|
||||
data->seq_num = priv->seq_num;
|
||||
|
|
|
@ -35,7 +35,7 @@ GstD3D11IpcServer * gst_d3d11_ipc_server_new (const std::string & address,
|
|||
GstFlowReturn gst_d3d11_ipc_server_send_data (GstD3D11IpcServer * server,
|
||||
GstSample * sample,
|
||||
const GstD3D11IpcMemLayout & layout,
|
||||
const std::wstring & name,
|
||||
HANDLE handle,
|
||||
GstClockTime pts);
|
||||
|
||||
void gst_d3d11_ipc_server_stop (GstD3D11IpcServer * server);
|
||||
|
|
|
@ -70,25 +70,8 @@ enum
|
|||
#define DEFAULT_MIN_BUFFER_SIZE 0
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
struct GstD3D11IpcSinkResource
|
||||
{
|
||||
~GstD3D11IpcSinkResource ()
|
||||
{
|
||||
if (handle)
|
||||
CloseHandle (handle);
|
||||
}
|
||||
|
||||
HANDLE handle = nullptr;
|
||||
std::wstring name;
|
||||
};
|
||||
|
||||
struct GstD3D11IpcSinkPrivate
|
||||
{
|
||||
GstD3D11IpcSinkPrivate ()
|
||||
{
|
||||
prefix = gst_d3d11_ipc_get_resource_prefix ();
|
||||
}
|
||||
|
||||
GstD3D11Device *device = nullptr;
|
||||
|
||||
GstBufferPool *fallback_pool = nullptr;
|
||||
|
@ -97,10 +80,8 @@ struct GstD3D11IpcSinkPrivate
|
|||
GstD3D11IpcServer *server = nullptr;
|
||||
GstCaps *caps = nullptr;
|
||||
GstSample *prepared_sample = nullptr;
|
||||
HANDLE prepared_handle = nullptr;
|
||||
GstD3D11IpcMemLayout layout;
|
||||
std::wstring resource_name;
|
||||
std::wstring prefix;
|
||||
guint64 seq_num = 0;
|
||||
|
||||
std::mutex lock;
|
||||
|
||||
|
@ -670,10 +651,8 @@ gst_d3d11_ipc_sink_prepare (GstBaseSink * sink, GstBuffer * buf)
|
|||
GstD3D11IpcSinkPrivate *priv = self->priv;
|
||||
GstBuffer *uploaded;
|
||||
GstD3D11Memory *dmem;
|
||||
std::wstring name;
|
||||
GstVideoFrame frame;
|
||||
GstD3D11IpcSinkResource *resource;
|
||||
gint64 token = gst_d3d11_ipc_get_shared_resource_token ();
|
||||
HANDLE nt_handle = nullptr;
|
||||
|
||||
gst_clear_sample (&priv->prepared_sample);
|
||||
|
||||
|
@ -703,51 +682,15 @@ gst_d3d11_ipc_sink_prepare (GstBaseSink * sink, GstBuffer * buf)
|
|||
|
||||
gst_video_frame_unmap (&frame);
|
||||
|
||||
gst_d3d11_device_lock (dmem->device);
|
||||
resource = (GstD3D11IpcSinkResource *)
|
||||
gst_d3d11_memory_get_token_data (dmem, token);
|
||||
if (!resource) {
|
||||
ID3D11Resource *d3d11_resource =
|
||||
gst_d3d11_memory_get_resource_handle (dmem);
|
||||
HRESULT hr;
|
||||
ComPtr < IDXGIResource1 > dxgi_resource;
|
||||
std::wstring name = priv->prefix + std::to_wstring (priv->seq_num);
|
||||
HANDLE handle;
|
||||
|
||||
priv->seq_num++;
|
||||
|
||||
hr = d3d11_resource->QueryInterface (IID_PPV_ARGS (&dxgi_resource));
|
||||
if (!gst_d3d11_result (hr, dmem->device)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't get IDXGIResource1 interface");
|
||||
gst_d3d11_device_unlock (dmem->device);
|
||||
gst_buffer_unref (uploaded);
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
hr = dxgi_resource->CreateSharedHandle (nullptr,
|
||||
DXGI_SHARED_RESOURCE_READ, name.c_str (), &handle);
|
||||
if (!gst_d3d11_result (hr, dmem->device)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't create shared handle");
|
||||
gst_d3d11_device_unlock (dmem->device);
|
||||
gst_buffer_unref (uploaded);
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
resource = new GstD3D11IpcSinkResource ();
|
||||
resource->handle = handle;
|
||||
resource->name = name;
|
||||
/* *INDENT-OFF* */
|
||||
gst_d3d11_memory_set_token_data (dmem, token, resource,
|
||||
[] (gpointer data) -> void {
|
||||
delete (GstD3D11IpcSinkResource *) data;
|
||||
});
|
||||
/* *INDENT-ON* */
|
||||
if (!gst_d3d11_memory_get_nt_handle (dmem, &nt_handle)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't get NT handle");
|
||||
gst_buffer_unref (uploaded);
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
gst_d3d11_device_unlock (dmem->device);
|
||||
|
||||
priv->prepared_sample = gst_sample_new (uploaded,
|
||||
priv->caps, nullptr, nullptr);
|
||||
priv->resource_name = resource->name;
|
||||
priv->prepared_handle = nt_handle;
|
||||
|
||||
gst_buffer_unref (uploaded);
|
||||
|
||||
|
@ -805,7 +748,7 @@ gst_d3d11_ipc_sink_render (GstBaseSink * sink, GstBuffer * buf)
|
|||
}
|
||||
|
||||
ret = gst_d3d11_ipc_server_send_data (priv->server, priv->prepared_sample,
|
||||
priv->layout, priv->resource_name, pts);
|
||||
priv->layout, priv->prepared_handle, pts);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue