我正在使用FFmpeg库来接收和解码基于UDP的H.264 / MPEG-TS,其中最小延迟(MediaElement无法处理)。
在专用的FFmpeg线程上,我正在拉PixelFormats.Bgr32视频帧进行显示。我已经尝试过InteropBitmap:
_section = CreateFileMapping(INVALID_HANDLE_VALUE, IntPtr.Zero, PAGE_READWRITE, 0, size, null);
_buffer = MapViewOfFile(_section, FILE_MAP_ALL_ACCESS, 0, 0, size);
Dispatcher.Invoke((Action)delegate()
{
_interopBitmap = (InteropBitmap)Imaging.CreateBitmapSourceFromMemorySection(_section, width, height, PixelFormats.Bgr32, (int)size / height, 0);
this.Source = _interopBitmap;
});
然后每帧更新:
Dispatcher.Invoke((Action)delegate()
{
_interopBitmap.Invalidate();
});
但性能非常差(跳帧,高CPU使用率等)。
我也尝试过WriteableBitmap:FFmpeg将帧放在_writeableBitmap.BackBuffer和每帧更新中:
Dispatcher.Invoke((Action)delegate()
{
_writeableBitmap.Lock();
});
try
{
ret = FFmpegInvoke.sws_scale(...);
}
finally
{
Dispatcher.Invoke((Action)delegate()
{
_writeableBitmap.AddDirtyRect(_rect);
_writeableBitmap.Unlock();
});
}
遇到几乎相同的性能问题(使用各种DispatcherPriority测试)。
非常感谢任何帮助。
答案 0 :(得分:1)
我知道为时已晚,但我为那些努力解决这个问题的人写了这个答案。 最近,我使用InteropBitmap完成了一个渲染项目,其中我能够在一个核心i7 1.6 Ghz CPU + 8Gb RAM笔记本电脑上同时在一个WPF窗口中运行大约16个媒体播放器组件,速度为25fps。 以下是我为性能调整所做的提示:
首先,我没有让GC处理我的视频数据包。我使用Marshal.AllocateHGlobal分配内存,只要我需要实例化视频帧,并在渲染后立即使用Marshal.FreeHGlobal进行Disposed。
其次,我为每个媒体播放器创建了一个调度程序线程。有关详细信息,请阅读" https://blogs.msdn.microsoft.com/dwayneneed/2007/04/26/multithreaded-ui-hostvisual/"。
第三,对于宽高比,通常是调整大小的目的,我使用了原生的EmguCV库。这个库对性能有很大帮助,而不是使用位图和叠加等。
我认为这些步骤可以帮助每个需要使用InteropBitmap等手动渲染的人。