Как правильно обновлять окно WPF, вывод видео

Здравствуйте. Очередная проблемка на тему декодирования видео.
Использую все тот же OpenH264 lib. Декодирую кадры и рисую их на форме.
Но вот возникает проблема что при частоте 30 фпс я естественно пытаюсь заливать данные в контрол с этой частотой и у меня можно засказать зависает весь GUI формы. Чтобы остановить потом проигрывание приходится нажимать на кнопку 100500 раз пока наконец событие не проскочит в код.

И это всего 30 фпс … а если видос будет в 100 фпс. Как быть то ним?? Как вообще VLC отрисовывает так что не заметно этой тормозни?

А как это происходит?

Наверно надо всё, кроме самой отрисовки, делать в другом потоке.

Так и есть. Запускаю отдельный поток, он декодирует и затем шлет Dispather.BeginInvoke для обновления.
А вообще есть какая нибудь максимальная скорость с которой можно обновление формы делать???

А как обновляется?
Может само обновление много времени занимает. Еще о GC помнить надо если там создаются новые объекты каждый раз.

public void ShowImage(IntPtr ptr)
        {
            Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Render, (SendOrPostCallback)delegate
            {
                try
                {
                    this.bitmapPresenter.Presenter.WritePixels(bitmapPresenter.RenderRect, ptr, bitmapPresenter.FrameSize, bitmapPresenter.Stride);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
            }, null);
            Interlocked.Increment(ref this.bitmapPresenter.FramesCount);
        }

Вроде ничего такого страшного нету.
Сам презентер это

public WriteableBitmap Presenter = null;

В документации советуют

For greater control over updates, and for multi-threaded access to the back buffer, use the following workflow.

  1. Call the Lock method to reserve the back buffer for updates.
  2. Obtain a pointer to the back buffer by accessing the BackBuffer property.
  3. Write changes to the back buffer. Other threads may write changes to the back buffer when the WriteableBitmap is locked.
  4. Call the AddDirtyRect method to indicate areas that have changed.
  5. Call the Unlock method to release the back buffer and allow presentation to the screen.

Хотя если всё перерисовывать, то наверно не важно. Но BeginInvoke видимо не нужен.


Вообще профайлер надо использовать при проблемах с производительностью.
Стандартный в меню Analyze, или от JetBrains.


Я бы наверно попробовал какой-нибудь готовый компонент для видео.
Может быть со стандартным MediaElement или этим как-то можно.

Или хотя бы посмотреть как реализовано.

MediaElement как-то использует OnRender + DrawingContext.

Там вроде DirectX внутри.

Ну да … у меня есть в версии с vlc реализация такого.
А вообще как думаете на чем будет быстрее на WPF или на WF?

Мне почему то кажется что WPF это сделано для красивых приложений в ущерб производительности. Сколько проектов не делал вечно в них возникают какие то траблы при больших объемах данных, либо высоких скоростях обработки. И постоянно какие то костыли предлагается выпиливать.

Сейчас вот новая задача требует получение данных с камеры в 200 кадров в сек. Весь в сомнениях на WF делать или WPF.

При больших объемах везде проблемы будут если без виртуализации и прочих оптимизаций, в винформс вроде бы нет ничего особенного по сравнению с WPF, разве что может быть разобраться проще.

Так а UI тут причем? Монитор же не 200 Гц наверно ))

Ну если я буду 200 раз в сек пытаться обновлять контрол на форме то мне кажется это отобразится на работе GUI.
И еще. Вот в медиаэлемент есть метод OnRender. Как я понял этот метод вызывает сама система для всех компонентов приложения. А в WF я что то такого не нашел.
Там я переопределяю OnPaint но чтобы компонент перерисовался мне нужно обязательно вызвать Invalidate(). Но мне кажется это не самый лучшый способ вызывать из разных частей кода перерисовку исли вдруг изменилось состояние объекта.

Так а его ж и нет смысла 200 раз обновлять если монитор не 200 Гц.