RAM获取帧的使用

本文关键字:获取 RAM | 更新日期: 2023-09-27 18:16:40

我创建了一个c#应用程序,它在输入中接收RGB流,然后压缩流并将其保存在磁盘上。对于我的测试,我正在运行一个应用程序,作为服务器(在同一台pc上),它输出视频。

我的客户端应用程序的核心是:
void client_ColorFrameReady(object sender, ColorFrameReadyEventArgs e)
{
    if (writer != null)
    {
        count++;
        if (count % 2 == 0)
            writer.WriteVideoFrame(ResizeBitmap(BitmapImage2Bitmap(e.ColorFrame.BitmapImage), 320, 240));
        }
        else
        {
            writer.Close();
        }
    }
}

表示writer的类型为aforge.net库中的VideoFileWriter

我的应用程序运行良好,但是我有一个与RAM使用量有关的问题。

当我的应用程序从服务器应用程序(流输出视频的应用程序)获取帧时,所使用的RAM随时间线性增加。

执行writer.Close()时释放内存。

BitmapImage2Bitmap和ResieBitmap方法如下:

private Bitmap BitmapImage2Bitmap(BitmapImage bitmapImage)
{
    // BitmapImage bitmapImage = new BitmapImage(new Uri("../Images/test.png", UriKind.Relative));
    using (MemoryStream outStream = new MemoryStream())
    {
         BitmapEncoder enc = new BmpBitmapEncoder();
         enc.Frames.Add(BitmapFrame.Create(bitmapImage));
         enc.Save(outStream);
         System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(outStream);
         // return bitmap; <-- leads to problems, stream is closed/closing ...
         return new Bitmap(bitmap);
    }
}
private static Bitmap ResizeBitmap(Bitmap sourceBMP, int width, int height)
{
    Bitmap result = new Bitmap(width, height);
    using (Graphics g = Graphics.FromImage(result))
    g.DrawImage(sourceBMP, 0, 0, width, height);
    return result;
}

我可以在我的应用程序中限制RAM的使用吗?

RAM获取帧的使用

我总是使用

你不是。不幸的是,你也会在不该用的时候用它。每一帧都有三个位图对象被"泄露"。

在MemoryStream上使用使用会遇到麻烦。并且通过复制位图修补了这个问题,但是位图对象没有被处理。解决这个问题的正确方式,做而不是处置MemoryStream。不释放MemoryStream是可以的,当你不使用MemoryStream(Stream)构造函数时,它只使用内存并且没有可释放的成员。现在您也不再需要使用Bitmap(image)构造函数创建的副本了。这是一个.

BitmapImage2Bitmap()返回的位图没有被处理。这是两个。

ResizeBitmap()返回的位图没有被处理。三。

应该是这样的:

using (var frame = BitmapImage2Bitmap(e.ColorFrame.BitmapImage))                   
using (var thumb = ResizeBitmap(frame, 320, 240)) {
    writer.WriteVideoFrame(thumb);
}

:

private Bitmap BitmapImage2Bitmap(BitmapImage bitmapImage)
{
    var outStream = new MemoryStream();  
    var enc = new BmpBitmapEncoder();
    enc.Frames.Add(BitmapFrame.Create(bitmapImage));
    enc.Save(outStream);
    return new System.Drawing.Bitmap(outStream);
}

你可能仍然有一个问题,正如我在评论中提到的,这段代码肯定比原来的代码快,避免了位图复制,但仍然不会烧橡胶。