最近负责高清录播系统的开发,使用的是windows media format 作为编码器,用directshow采集音频和视频。使用ISampleGrabber中的回调函数来获取采集到的音视频数据。在回调函数中,获取音频数据代码如下(注意此处采集到的每一帧音频数据是半秒数据):
STDMETHODIMP BufferCB(double dblSampleTime, BYTE * pBuffer, long lBufferSize )
{
//可能会存在不可预知的问题,此处返回的音频数据为半秒的数据。。。。
//对返回的数据长度进行判断,使用队列来管理数据帧
if(!pBuffer)return 0;
//处理音频数据
if(lBufferSize<m_dwAvgBytesPerSec)
{
memcpy(m_pBuf[m_nIndex]+m_bufOffset,pBuffer,lBufferSize);
m_bufOffset = m_bufOffset+lBufferSize;
if(m_bufOffset>=m_dwAvgBytesPerSec)
{
m_bufOffset = 0;
m_nIndex = (m_nIndex+1)%10;
}
//////////////////////////////////////////////////////////////////////////
if(m_nIndex==1)
{
m_bReady = TRUE;
}
}
return 0;
}
采集视频的代码如下:
STDMETHODIMP BufferCB(double dblSampleTime, BYTE * pBuffer, long lBufferSize )
{
// nFrame++;
if (!pBuffer)return E_POINTER;
if(m_ImageData && m_bFrame)
{
if(m_FrameLen<lBufferSize)
return 0;
memcpy(m_ImageData,pBuffer,lBufferSize);
}
m_bFrame = FALSE;
return 0;
}
在主程序中开启两个线程,一个线程数压缩每一帧采集到的数据,另外一个线程每一次有数据到达时,设置采集每一帧音视频数据为真。按照此方法,最后录制的视频文件会出现音视频不同步,其中音频总是比视频慢0.5s,且在播放一段时间后,音频会出现乱序的现象。针对于以上现象,出现的关键原因是在directshow中,采集音频的FIlter默认把数据缓冲设置为0.5s,这就导致了较大的延迟,最终导致了音视频不同步。解决办法是把音频采集到的数据缓冲开为40ms,在每一次运行音频捕获数据的回调函数中,设置一个进行每一帧音视频压缩的信号,这样在压缩为wmv格式的视频文件后,播放时,音频和视频都很流畅。