Что такое быстрый способ создания и создания видео в WPF? - PullRequest
5 голосов
/ 23 ноября 2010

Я пишу видеоплеер для воспроизведения кадров, снятых нашей ASIC. Они в произвольном формате, и мне была предоставлена ​​функция, которая декодирует состояния ASIC. Видео может быть любого размера от 640х480 до 2560х1200 (!!!). Выходные данные каждого цикла состояния составляют 16x16 блоков пикселей, которые я должен вставить в видео на экране.

Каждый раз, когда необходимо обновить экран, у меня есть следующая информация:

  • Ширина блока
  • Высота блока
  • X координата начала блока
  • Координата Y начала блока
  • 1-D массив информации о цвете пикселей RGB32

Основные ограничения:

  • .NET 3.5
  • Нет небезопасного кода

Я провел это утро, пробуя WriteableBitmap и используя его в качестве источника изображения, что-то вроде этого:

    private WriteableBitmap ImageSource;

    public MainWindow()
    {
        InitializeComponent();

        ImageSource = new WriteableBitmap(FrameWidth, FrameHeight, 96, 96, PixelFormats.Bgr32, null);
        ImagePanel.Source = ImageSource;
    }

    private void DrawBox(byte Red, byte Green, byte Blue, int X, int Y)
    {
        int BoxWidth = 16;
        int BoxHeight = 16;
        int BytesPerPixel = ImageSource.Format.BitsPerPixel / 8;

        byte[] Pixels = new byte[BoxWidth * BoxHeight * BytesPerPixel];

        for (int i = 0; i < Pixels.Length; i += 4)
        {
            Pixels[i + 0] = Blue;
            Pixels[i + 1] = Green;
            Pixels[i + 2] = Red;
            Pixels[i + 3] = 0;
        }

        int Stride = BoxWidth * BytesPerPixel;
        Int32Rect DrawBox = new Int32Rect(X, Y, BoxWidth, BoxHeight);

        ImageSource.Lock();
        ImageSource.WritePixels(DrawBox, Pixels, Stride, 0);
        ImageSource.Unlock();
    }

Это работает, мое видео воспроизводится на экране, но оно не работает. Нигде в реальном времени скорость игры. Есть ли лучший способ, кроме процедурного создания серии растровых изображений, сделать это, что я не вижу? Я читал кое-что о D3Dimage, но похоже, что это больше для экспорта 3D-сцены в растровое изображение. Предложения здесь?

1 Ответ

6 голосов
/ 23 ноября 2010

Если я правильно понимаю, вы получаете блок 16 * 16 пикселей в качестве захвата, а в приведенном выше примере вы обновляете растровое изображение с возможностью записи для каждого из этих обновлений.

Это выглядит как много оттоккак рендеринг запускается на каждом блоке.

Не лучше ли:

  • Поддерживать однобайтовый буфер, который представляет весь кадр.
  • Обновлять буфер с вашими 16 * 16 блоками, как выполучить их.
  • Когда вы получили все блоки для кадра, запишите буфер в растровое изображение.
  • Повторно использовать буфер кадров для следующего кадра, перезаписав его.

Таким образом, вы получите гораздо меньше оттока при рендеринге, поскольку вы не будете запускать рендеринг длякаждый блок, который вы получаете, но только для каждого кадра.

Обновление 1

Я бы также рассмотрел использование Bgr24 в качестве формата пикселей, если вы не используете альфа-канал.Таким образом, у вас будет 3 байта на пиксель, а не 4, так что намного меньше издержек.

Обновление 2

Если все еще слишком медленно для большого кадраРазмеры, вы также можете рассмотреть следующее, что добавляет сложности, хотя.

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

Обновление 3

Если ваш массив информации о цветах пикселей из вашего захвата находится вправильный формат, вы можете попробовать использовать Buffer.BlockCopy для массового копирования массива исходных пикселей в массив кадрового буфера.Вы должны сохранить свой растровый формат как bgr32.Этот метод копирования массивов низкого уровня может привести к некоторому приросту производительности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...