ネットワーク ソースからのビデオ ストリームを XAML で表示する必要があります。ビデオ フレームは、未定義の間隔で発生する可能性があります。それらは既にアセンブルされ、デコードされ、メモリ マップ ファイルの BGRA8 形式で表示されます。XAML フロントエンドは C# で、バックエンドは WinAPI を使用して C で記述されています。
C# では、このファイルのハンドルを持っています。
以前は .NET 4.5 で、このハンドルから InteropBitmap を作成し、新しいフレームの到着時にSystem.Windows.Interop.Imaging.CreateBitmapSourceFromMemorySection
呼び出していました。Invalidate
これを XAMLInteropBitmap
として使用したよりも。Source
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 イメージのソースとして使用できます (無効化時にプロパティの変更を発生させることを忘れないでください。そうしないと、イメージは更新されません)。
より良い、またはより標準的な方法はありますか?無効化時に追加の memcpy が必要ないようにするにはWriteableBitmap
どうすればよいですか?m_image
更新: MediaElement を使用して、圧縮されていないビットマップのシーケンスを表示し、それから利益を得ることができるのだろうか? MediaElement は非常に優れた機能であるフィルターをサポートしています。