Решение проблемы нехватки памяти при записи с видеоустройства в WPF - PullRequest
0 голосов
/ 09 июля 2011

Я получаю входные данные от устройства ввода видео и успешно выводлю их в System.Windows.Controls.Image в форме WPF. Я хочу записать полученное видео и сохранить его на диск. Я пошел об этом так:

  • создал класс, в котором хранится A BitmapImage и время, затрачиваемое на каждый кадр, выводимый на экран. BitmapImage создается из BitmapSource, созданного непосредственно из видеовхода
  • У меня есть список вышеупомянутого класса, каждый раз, когда принимается новый кадр, я создаю такой класс и добавляю его в список
  • когда я прихожу, чтобы сохранить его, я использую Splicer для создания WMV, а затем сохраняю его на диск

Проблема в том, что примерно через 10 секунд (~ 400 кадров) я получаю исключение OutOfMemoryException в разных точках при каждом запуске программы.

Я пытался решить эту проблему, сжимая каждый сохраненный BitmapImage в png, jpeg и tiff, но это приводило к резкому падению частоты кадров и фактически не дало мне гораздо больше времени.

Я пошел по этому пути совершенно неправильно? Или есть какая-то работа или что-то, что кто-то может порекомендовать?


Редактировать

Когда вас попросили вставить код, вот соответствующий код: Это класс, который хранит изображение

    public class ImageVideoFrame
    {
        private System.Drawing.Image frame;
        private long time;

        public System.Drawing.Image Frame
        {
            get { return frame; }
        }

        public long Time
        {
            get { return time; }
        }

        public ImageVideoFrame(System.Drawing.Image frame, long time)
        {
            this.frame = frame;
            this.time = time;
        }

        public void Dispose()
        {
            frame.Dispose();

        }
    }

    Bitmap GetBitmap(BitmapSource source)
    {
        MemoryStream ms = new MemoryStream();
        BitmapEncoder enc = new BmpBitmapEncoder();
        BitmapFrame frame = BitmapFrame.Create(source);
        enc.Frames.Add(BitmapFrame.Create(source));
        enc.Save(ms);
        Bitmap bm = new Bitmap(ms);

        ms.Close();

        return bm;
    }

А вот где каждый кадр рисуется и сохраняется:

public void DrawVideoFrame(PlanarImage img, System.Windows.Controls.Image dest)
        {
            // 32-bit per pixel, RGBA image
            BitmapSource tempSource  = BitmapSource.Create(img.Width, img.Height, 
            96, 96, PixelFormats.Bgr32, null, img.Bits, img.Width * img.BytesPerPixel);
            dest.Source = tempSource;


            if (recordVideo)    //record video is set elsewhere
            {
                videoRecordings.Add(new ImageVideoFrame(tempSource, 
                    DateTime.Now.Ticks / 10000));

             }

        }

Спасибо за помощь, ребята !!

Ответы [ 3 ]

0 голосов
/ 09 июля 2011

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

0 голосов
/ 09 июля 2011

Вы должны использовать только одно растровое изображение (опрос) и немедленно записать в файл.Вы не можете ждать после того, как пользователь нажимает кнопку Стоп.Что делать, если программа будет работать в течение 2 часов или более?

0 голосов
/ 09 июля 2011

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

Многие классы, с которыми вы работаете (например, Image), являются одноразовыми, поскольку они работают с неуправляемыми ресурсами. Убедитесь, что вы утилизируете (или используете оператор using(...)) все одноразовые экземпляры.

...