我需要在 XAML 中显示来自某个网络源的视频流。视频帧可以以未定义的间隔出现。它们已经被组装、解码并以 BGRA8 形式呈现在内存映射文件中。XAML 前端是用 C# 编写的,后端是使用 WinAPI 用 C 编写的。
在 C# 中,我有这个文件的句柄。
以前在 .NET 4.5 中,我使用此句柄创建 InteropBitmapSystem.Windows.Interop.Imaging.CreateBitmapSourceFromMemorySection
并调用Invalidate
新帧的到达。比我将它InteropBitmap
用于Source
XAML Image
。
现在我需要为 Windows 10 UAP 平台做同样的事情。.NET Core 中没有内存映射文件,因此我创建了一个 CX Windows 运行时组件。这是其中最重要的部分。
static byte* GetPointerToPixelData(IBuffer^ pixelBuffer, unsigned int *length)
{
if (length != nullptr)
{
*length = pixelBuffer->Length;
}
// Query the IBufferByteAccess interface.
ComPtr<IBufferByteAccess> bufferByteAccess;
reinterpret_cast<IInspectable*>(pixelBuffer)->QueryInterface(IID_PPV_ARGS(&bufferByteAccess));
// Retrieve the buffer data.
byte* pixels = nullptr;
bufferByteAccess->Buffer(&pixels);
return pixels;
}
void Adapter::Invalidate()
{
memcpy(m_bitmap_ptr, m_image, m_sz);
m_bitmap->Invalidate();
}
Adapter::Adapter(int handle, int width, int height)
{
m_sz = width * height * 32 / 8;
// Read access to mapped file
m_image = MapViewOfFile((HANDLE)handle, FILE_MAP_READ, 0, 0, m_sz);
m_bitmap = ref new WriteableBitmap(width, height);
m_bitmap_ptr = GetPointerToPixelData(m_bitmap->PixelBuffer, 0);
}
Adapter::~Adapter()
{
if ( m_image != NULL )
UnmapViewOfFile(m_image);
}
现在我可以使用 m_bitmap 作为 XAML 图像的源(并且不要忘记在无效时引发属性更改,否则图像将不会更新)。
有没有更好或更标准的方法?我怎样才能创建WriteableBitmap
,m_image
这样我就不需要额外的 memcpy 无效了?
更新:我想知道是否可以使用 MediaElement 显示未压缩位图序列并从中获得任何好处?MediaElement 支持过滤器,这是一个非常好的功能。