上一篇讲了怎么把视音频采集下来并合成一个AVI文件,但我们看这个AVI文件就发现,虽然很清晰,但就是大小太大了,录制短短10秒,可能就有100M以上,而且还有一个问题,就是录制只能是打开采集时开始,停止采集时停止,不能预览的时候随心所欲地录制。本篇就是要解决这些问题。
之前有一篇(使用DShow进行采集拍照)在讲实时拍照时曾用到过ISampleGrabber来抓取图像,然后设置缓存,从缓存中取数据然后生成图片,本篇也使用ISampleGrabber,但不使用缓存的方式,而是使用回调的方式抓取图像,在回调中先将RGB24的帧转换为YUV420,然后使用第三方的编码器X264对其进行编码。下面我们来做做看。大致的代码跟实时拍照那一篇差不多,不过设置回调的地方不一样,代码如下:
//设置视频分辨率、格式
IAMStreamConfig *pConfig = NULL;
m_pCapture->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
m_pVideoFilter, IID_IAMStreamConfig, (void **) &pConfig);
AM_MEDIA_TYPE *pmt = NULL;
VIDEO_STREAM_CONFIG_CAPS scc;
pConfig->GetStreamCaps(nResolutionIndex, &pmt, (BYTE*)&scc); //nResolutionIndex就是选择的分辨率序号
pmt->majortype = MEDIATYPE_Video;
pmt->subtype = MEDIASUBTYPE_RGB24; //抓取RGB24
pmt->formattype = FORMAT_VideoInfo;
pConfig->SetFormat(pmt);
m_pGrabberFilter->QueryInterface(IID_ISampleGrabber, (void **)&m_pGrabber);
HRESULT hr = m_pGrabber->SetMediaType(pmt);
if(FAILED(hr))
{
AfxMessageBox(_T("Fail to set media type!"));
return;
}
//是否缓存数据,缓存的话,可以给后面做其他处理,不缓存的话,图像处理就放在回调中
m_pGrabber->SetBufferSamples(FALSE);
m_pGrabber->SetOneShot(FALSE);
mCB