簡體   English   中英

使用RAM獲取幀

[英]Usage of RAM acquiring frames

我創建了一個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();
        }
    }
}

類型writerVideoFileWriteraforge.net庫。

我的應用程序運行良好,但我遇到了與使用的RAM量有關的問題。

當我的應用程序正在獲取幀時,從服務器應用程序(流出視頻的應用程序)使用的RAM隨時間線性增加。 只有在執行writer.Close()時才釋放RAM。

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的使用嗎?

我總是使用

你不是。 不幸的是,你也應該使用它。 每個幀都有三個位圖對象在這里'泄露'。

通過使用將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);
}

你可能仍然有一個firehose問題,正如我在評論中提到的,這個代碼肯定比原來快,因為避免了位圖復制,但仍然不會燒橡膠。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM