I'm working on a Unity native plugin that runs a gstreamer pipeline in the background, decodes it using hardware decoding, then copies the texture over to a render texture to be displayed in Unity.
I have my GStreamer already working, I can run it from Unity and it creates a window with the camera output, all decoded on the GPU. From what I can see, GStreamer has a parameter in the d3d11videosink to "draw-on-shared-texture" of format DXGI_FORMAT_R8G8B8A8_UNORM.
It also has an signal that gets called when gstreamer is about to draw, and a draw command to draw on a "shared handle".
I've only seen code out there to copy a decoded texture on the CPU and copying it back on the GPU, but never GPU => GPU copies. How do I go about it?
Also, I know that unity recommends doing all graphic operations in the reader thread using GL.IssuePluginEvent, but how am I supposed to do that when GStreamer doesn't let me access the texture when I want, only during the begin_draw callback.
I don't know much about DX11 or native unity plugin in general, and I am very lost. Any help would be appreciated.
Here's some code for my failed attempt at trying to get GStreamer to draw onto my ID3D11Resource pointer given by unity using RenderTexture.GetNativePtr():
static GstFlowReturn begin_draw_callback(GstElement* videosink, gpointer data)
{
GstApp* app = (GstApp*)data;
ID3D11Resource* resPtr = app->GetResourcePtr();
if (resPtr == nullptr) {
return GST_FLOW_OK;
}
// Your custom code here
Debug::Log("BEGIN DRAW");
HANDLE handle;
IDXGIResource1* pResource;
HRESULT res1 = resPtr->QueryInterface(__uuidof(IDXGIResource1), (void**)&pResource);
HRESULT res2 = pResource->CreateSharedHandle(
nullptr, DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE, nullptr, &handle);
std::string res1Str = HRESULTToString(res1);
std::string res2Str = HRESULTToString(res2);
Debug::Log(res1Str);
Debug::Log(res2Str);
gpointer shard_handle = (gpointer)pResource;
guint texture_misc_flags = D3D11_RESOURCE_MISC_FLAG::D3D11_RESOURCE_MISC_SHARED;
guint64 acquire_key = NULL;
guint64 release_key = NULL;
g_signal_emit_by_name(videosink, "draw", shard_handle, texture_misc_flags, acquire_key, release_key, nullptr);
return GST_FLOW_OK;
}
CreateSharedHandleisn't working. Maybe consider creating a sharable texture in your plugin using Unity's provided device, and once GStreamer's draw action_signal is called, copy back the result to the unity render texture? \$\endgroup\$