2013-11-11 2 views
4

Я использую библиотеку FFmpeg для приема и декодирования H.264/MPEG-TS через UDP с минимальным латентностью (что-то MediaElement не может обрабатывать).Каков наиболее эффективный способ визуализации неуправляемых видеокадров в WPF?

На выделенном потоке 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(); 
}); 

Но производительность очень плохо (пропуск кадров, высокая загрузка процессора и т.д.).

Я также попытался 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

Я знаю, что уже слишком поздно, но я пишу этот ответ тем людям, которые изо всех сил пытаются решить эту проблему. Недавно я сделал проект рендеринга, используя InteropBitmap, в котором я смог одновременно запустить около 16 компонентов медиа-плеера в окне WPF на ядре с процессором i7 1,6 ГГц с процессором + 8 Гб оперативной памяти с частотой 25 кадров в секунду. Вот советы, которые я взял для настройки производительности:

Прежде всего, я не позволял GC обрабатывать мои видеопакеты. Я выделил память, используя Marshal.AllocateHGlobal везде, где мне нужно было создать экземпляр видеофрагмента и утилизировать с помощью Marshal.FreeHGlobal, как только я сделал рендеринг.

Во-вторых, я создал поток диспетчера для каждого отдельного медиаплеера. Для получения дополнительной информации прочтите «https://blogs.msdn.microsoft.com/dwayneneed/2007/04/26/multithreaded-ui-hostvisual/».

В-третьих, для формата изображения и, как правило, для изменения размера, я использовал собственную библиотеку EmguCV. Эта библиотека очень помогла мне в производительности, а не использовала растровые изображения и наложения и т. Д.

Я думаю, что эти шаги помогут всем, кому необходимо визуализировать вручную, используя InteropBitmap или т. Д.