使用Accord开始视频捕获时,CPU和内存消耗增加了。

7

我正在使用Accord.Video.FFMPEG录制屏幕。我遇到的问题是CPU和内存利用率都太高了。通常情况下,我们的进程使用最多2%的CPU和30MB的内存,但是当我们开始视频捕获时,CPU会升高到17%,内存则达到700MB。我尝试使用

GC.Collect();

但没有什么作用。

private void video_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
    try
    {
        if (this._isRecording)
        {
            int screenRecordingLength = screenRecrodingRule != null ? screenRecrodingRule.length : 500;
            //Bitmap frame;
            Bitmap frame = eventArgs.Frame;
            {
                Graphics graphics = Graphics.FromImage(frame);
                try
                {
                    CURSORINFO pci;
                    pci.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(CURSORINFO));
                    if (GetCursorInfo(out pci))
                    {
                        if (pci.flags == CURSOR_SHOWING)
                        {
                            int x = pci.ptScreenPos.x - screenLeft;
                            int y = pci.ptScreenPos.y - screenTop;

                            Color c = Color.Yellow;
                            float width = 2;
                            int radius = 30;
                            if ((Control.MouseButtons & MouseButtons.Left) != 0 || (Control.MouseButtons & MouseButtons.Right) != 0)
                            {
                                c = Color.OrangeRed;
                                width = 4;
                                radius = 35;
                            }
                            Pen p = new Pen(c, width);

                            graphics.DrawEllipse(p, x - radius / 2, y - radius / 2, radius, radius);
                            DrawIcon(graphics.GetHdc(), x, y, pci.hCursor);
                            graphics.ReleaseHdc();
                        }
                    }
                    this._writer.WriteVideoFrame(frame, (DateTime.Now - videoStartTime));
                }
                catch (Exception ex)
                {
                   // this._writer.WriteVideoFrame(frame, (DateTime.Now - videoStartTime));
                }

                //this._writer.Flush();
            }
            if (DateTime.Now.Subtract(videoStartTime).TotalSeconds > screenRecordingLength)
            {
                log.DebugFormat("SR: Stopping the video capturing as the time limit is exceded config length:{0}, video length: {1}.", screenRecrodingRule.length, DateTime.Now.Subtract(videoStartTime).TotalSeconds);
                isVideoCaptureCompeted = true;
                previousScreenRecodringRule = null;
                _streamVideo.SignalToStop();
                Thread.Sleep(100);
                _writer.Flush();
                Thread.Sleep(100);
                _writer.Close();
                StopVideoCapture();
            }
        }
        else
        {
            _streamVideo.SignalToStop();
            Thread.Sleep(100);
            _writer.Flush();
            Thread.Sleep(100);
            _writer.Close();
        }
    }
    catch (Exception ex)
    {
        //log.ErrorFormat("SR: Exception occured while capturing the video {0}, {1}", ex.Message, ex.StackTrace);
    }
}

1
录制屏幕是一项CPU密集型任务,因此17%的CPU使用率对于它来说并不算太糟糕。内存可能可以更低,但由于您没有处理任何内容,这也并不令人意外。 - Evk
如果您与该代码共享测试应用程序,我可以使用分析器检查其性能/内存泄漏。此外,您还可以使用第三方工具(如ShareX(带有ffmpeg屏幕捕获))来捕获相同的屏幕区域,并查看在相同条件下捕获时使用了多少CPU,但没有自定义绘图。 - dlxeon
1个回答

6

GraphicsPen都是可释放资源,建议先释放它们。

如果这样做没有帮助,你可以使用PerfView工具在应用程序运行时进行多次堆快照,并进行比较以找出未被销毁的对象。 Perfview可以显示CPU数据概要、.net内存分配以及一些与GC相关的统计信息(垃圾回收期间花费的时间等)。 在Channel9上有一个很好的教程。

最后,您可以获取完整的内存转储,然后使用WinDbg或Visual Studio(仅限Ultimate / Enterprise版)来分析大型对象引用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接