2010-09-08 54 views
4

我正在C++中开发一个屏幕录制实用程序。如何优化我的屏幕录制实用程序?

它基本上捕获桌面框架并创建一个AVI文件。该算法如下:

  1. 创建一个线程:在每秒thScreenCapture n倍(如5 fps)的this->m_hThread=CreateThread(NULL,0,thScreenCapture,this,0,NULL);
  2. 捕获桌面。

    obj->Capture();

  3. 在捕捉(),位图数据附加到AVI文件。

    this->appendBitmapToAvi(this->avifile, bmp);

此实用程序还记录声音。因此,在thScreenCapture方法中,声音数据也被附加到avi文件。

问题是,当帧数超过6帧(这可以根据硬件配置而变化)每秒捕获时,帧和声音之间出现滞后。

我正在寻求解决方案来优化算法。一个解决方案可能会缓存内存中的帧,而不是将它们全部附加到avi文件中。但是这会使代码更复杂,因为我必须处理在不同线程中捕获的声音数据。

您建议如何增加该实用程序支持的fps值而不会失去同步?

+0

你应该考虑directshow(见下面的答案)。它使用参考时钟和媒体帧的时间戳,以便同步音频和视频。虽然视频帧用于不连续的间隔,但音频帧的持续时间通常是可变的。 – 2010-09-20 12:34:19

+0

使用DirectX。你是否已经增加了进程/线程的优先级?除此之外,使用一个线程捕获和预处理图像缓冲区,另一个线程来缩放和转换等等。您也可以检测处理器/内核的数量,并为每个内核产生一个线程来推迟处理。不幸的是,我对音频毫无头绪。 – jweyrich 2010-09-20 15:00:50

回答

1

你是自己编写AVI文件吗?一个高尚的努力,但有API来帮助完成这项任务。

如果您正在开发Windows平台,我建议您考虑使用DirectShowMedia Foundation API将音频和视频多路复用到磁盘。 DirectShow是 API,用于在Windows平台上进行A/V捕获,流式传输和多路复用。

This article on CodeProject关于音频的讨论&视频同步问题以及DirectShow用于克服此困难的机制。

本质上,使用参考时钟并且帧被加时间戳。

有一个非常有用的新资源的active DirectShow communityTMH's website非常值得关注 - 他是MS MVP,是社区的活跃成员。

我希望这有助于!

+0

感谢您的建议。我使用的是开源AVI库,它工作得很好。我已经解决了很多问题,比如添加mp3音频数据(需要额外的头文件信息并花费数天的时间才能找到)。现在我需要的是加速我的捕捉引擎。 – Zafer 2010-09-22 10:22:07

1

你可以看看other screencasting software的来源,如CamStudio,看看他们是怎么做的。

如果你的程序是磁盘绑定的(我怀疑它是),那么事情可能通过压缩提高(这是天大的名称方案,如Camtasia工作室,如何运作)

+0

是的,这是磁盘绑定,这就是为什么我用我的问题中没有提到的优秀的Xvid编解码器压缩帧。 – Zafer 2010-09-08 22:14:34

+0

@Zafer:那么你将不得不记忆缓冲器的东西,否则你将不得不开发自己的编解码器。这就是Camtasia人做的 - 我写的是他们自己的编解码器。 DivX和XviD适用于普通电影视频,但可以为屏幕录像进行更多优化。 – 2010-09-08 22:21:13

+0

你知道关于编解码器开发的资源吗? – Zafer 2010-09-09 05:27:09

0

你目标是什么操作系统?如果你在Windows XP上工作,我会看看http://tmhare.mvps.org/downloads.htm的一些DirectShow代码,特别是Filter Graph Library。

+0

感谢您的链接。我的目标是Win XP,Vista和7。 – Zafer 2010-09-09 16:31:37

1

使用一个循环的双重或三重缓冲区来存储位图并发出每帧声音,并使用单独的线程将位图和声音添加到avi。因此,数据收集位于一个线程中,数据处于循环(线程安全)缓冲区,数据存储位于另一个线程中。

+0

A/V帧必须同步!缓冲不会解决这个问题! – 2010-09-20 08:04:46

+0

没错。我使用单独的线程来收集视频和音频数据,但将它们以同步的方式添加到avi文件进行交织。 – Zafer 2010-09-22 10:20:17

+0

@freefallr所以Zafer是以交错的方式进行的,这意味着在主线程中存储数据并在另一个线程中存储数据会更有意义。如我错了请纠正我。 – 2010-09-22 10:39:14