【发布时间】:2021-10-20 18:25:44
【问题描述】:
我为 Micorsoft HoloLens 2 创建 Unity 应用程序。
该应用使用 Windows.Media.Capture.MediaCapture 和 Microsoft.MixedReality.WebRTC 捕获和共享相机视频帧。
我在 MediaFrameReader.FrameArrived 事件中得到了一个由“NV12”格式化的 VideoMediaFrame.Direct3DSurface(Windows.Graphics.DirectX.Direct3D11.IDirect3DSurface)。
但我不知道如何从 IDirect3DSurface 对象中获取像素数据。
我在下面尝试过:
C# 代码
[DllImport("Direct3DSurfaceAccess")]
private static extern void Direct3DSurfaceAccess([MarshalAs(UnmanagedType.Interface)]Windows.Graphics.DirectX.Direct3D11.IDirect3DSurface d3dSurface);
// MediaFrameReader.FrameArrived event.
private void Nv12FrameArrived(MediaFrameReader sender, MediaFrameArrivedEventArgs args) {
using var mediaFrameReference = sender.TryAcquireLatestFrame();
// I could't find how to get pixel data from IDirect3DSurface using C# only.
// Use C++/WinRT for access IDirect3DSurface as below.
Direct3DSurfaceAccess(mediaFrameReference.VideoMediaFrame.Direct3DSurface);
}
C++ 代码
void __stdcall Direct3DSurfaceAccess(const winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DSurface* d3dSurface) {
// Here, confirmed that d3dSurface is not null.
try {
// Issue is here.
winrt::com_ptr<::Windows::Graphics::DirectX::Direct3D11::IDirect3DDxgiInterfaceAccess> dxgiInterfaceAccess;
d3dSurface->try_as(dxgiInterfaceAccess);
// App crashes on d3dSurface->try_as.
// Call other d3dSurface method as a test.
winrt::Windows::Graphics::DirectX::Direct3D11::Direct3DSurfaceDescription desc = d3dSurface->Description();
// Same above. App crashes on d3dSurface->Description.
// Unreachable to here...
// When succeeded to get the IDirect3DDxgiInterfaceAccess, read pixel data by below code.
winrt::com_ptr<::IDXGISurface> nativeSurface;
dxgiInterfaceAccess->GetInterface(IID_PPV_ARGS(nativeSurface.put()));
::DXGI_MAPPED_RECT rect;
nativeSurface->Map(&rect, DXGI_MAP_READ);
const BYTE* pixels = rect.pBits; // Read pixel data from the pointer.
nativeSurface->Unmap();
} catch (...) {
// Can't catch any exceptions.
// App freezes and downs on HoloLens 2.
}
}
我认为如何编组是错误的IDirect3DSurface。
如何从IDirect3DSurface获取像素数据?
【问题讨论】:
-
首先要做的是检查所有方法调用(GetInterface、Map 等)的 HRESULR 错误
-
@SimonMourier 谢谢。在此代码中省略了 HRESULT 检查以简化。在实际代码中,我检查了这一点。案例,应用程序在调用 d3dSurface 的方法(例如 try_as,描述)返回 HRESULT 之前崩溃。
-
你可以试试
Direct3DSurfaceAccess([MarshalAs(UnmanagedType.IInspectable)] object d3dSurface);吗 -
@SimonMourier 谢谢。我尝试了 UnmanagedType.IInspectable(和 UnmanagedType.IUnknown 太),但没有奏效。应用程序崩溃了。
-
你应该发布一个复制样本。
标签: c# c++ unity3d windows-runtime hololens