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:
Seungha Yang 2023-06-05 22:34:27 +09:00 committed by GStreamer Marge Bot
parent 1e5343f0c6
commit ef1853aa8d
6 changed files with 139 additions and 232 deletions

View file

@ -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;
}

View file

@ -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);

View file

@ -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 ();

View file

@ -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;

View file

@ -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);

View file

@ -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;
}