录制视频时画面出现间断性停顿的解决方法

使用 Microsoft DirectShow SDK 同时采集视频和音频,录制的视频画面在播放时出现间断性停顿,如果去掉音频采集则画面播放恢复正常,本文介绍解决这一问题的方法。

产生原因

使用 DiectShow 进行音频采集时,默认情况下 Audio Capture Filter 使用了 0.5 秒的缓冲以保证声音的连续性,而视频采集默认情况下没有设置缓冲时间,这样在录制生成的 ASF 文件时,同时写入的音视频采样数据时间戳存在 0.5 秒的差异,在播放 ASF 文件时就会导致视频数据等待音频数据的情况,在效果上即为视频画面出现间断性停顿。

解决方式

正常情况下,音频缓冲区没有必要设置为 0.5 秒这么大,一般设为 50 至 80 毫秒足够了,但也不能太小,否则会导致音频采集的效率,影响音质。具体设置方法如下:

  1. 枚举 IAMBufferNegotiation 接口。可以从 ICaptureGraphBuilder2 枚举,也可以从音频设备的 ICapturePin 里枚举。

    1. IAMBufferNegotiation* pNeg = NULL;
    2. ICaptureGraphBuilder2->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio, m_pAudioCaptureFilter, IID_IAMBufferNegotiation, (void **)&pNeg);
  2. 设置缓冲区大小。

    1. ALLOCATOR_PROPERTIES prop={0};
    2. prop.cbBuffer = 4096; // this is the size of audio data for each frame
    3. prop.cBuffers = 32; // set the frames of buffer zone
    4. prop.cbAlign = 16;
    5. hr = pNeg->SuggestAllocatorProperties(&prop);
    6. pNeg->Release();

通过上述设置后再进行音视频采集即可解决画面停顿的问题。