我需要在XAML中显示来自某个网络源的视频流。视频帧可能以不确定的间隔出现。它们已经在内存映射文件中以BGRA8形式组装,解码和呈现。 XAML前端位于C#中,后端使用WinAPI以C语言编写。
在C#中,我有一个这个文件的句柄。
以前在.NET 4.5中我使用System.Windows.Interop.Imaging.CreateBitmapSourceFromMemorySection
从此句柄创建InteropBitmap,并在到达新帧时调用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支持过滤器,这是一个非常好的功能。