3

入力で RGB ストリームを受け取り、ストリームを圧縮してディスクに保存する C# アプリケーションを作成しました。私のテストでは、ビデオをストリーミングするサーバー(同じ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はライブラリVideoFileWriterからのものです。aforge.net

アプリケーションは正常に動作しますが、RAM の使用量に関連する問題があります。

私のアプリケーションがフレームを取得するとき、サーバー アプリケーション (ビデオをストリーミングするアプリケーション) から使用される 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 の使用を制限できますか?

4

1 に答える 1

4

いつも使ってます

あなたは違う。残念ながら、使用してはいけない場合にも使用します。ここでは、フレームごとに3 つのビットマップ オブジェクトが「リーク」されています。

MemoryStream でusing を使用して問題が発生しました。ビットマップをコピーして問題にパッチを当てましたが、ビットマップオブジェクトは破棄されていません。これを正しい方法で修正し、MemoryStream を破棄しないでください。MemoryStream を破棄しないことは問題ありません。MemoryStream(Stream) コンストラクターを使用しない場合、メモリのみを使用し、破棄可能なメンバーはありません。Bitmap(image) コンストラクターで作成したコピーももう必要ありません。それは1つです。

BitmapImage2Bitmap() によって返されたビットマップは破棄されていません。それは2つです。

ResizeBitmap() によって返されたビットマップは破棄されていません。それは3つです。

次のようになります。

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);
}

コメントで述べたように、まだ消防ホースの問題があるかもしれません.

于 2013-06-04T09:53:16.853 に答える