我正在构建一个DirectShow图。 我有视频捕获滤波器,将其输出引脚连接到SampleGrabber的输入引脚。 在连接两个引脚之前,我配置输出引脚如下:
HRESULT GraphBuilder::applyVideoFormat()
{
if( !pVideoCaptureFilter_ )
return E_FAIL;
CComPtr<IPin> pPin;
pPin.Attach( findCategoryPin( pVideoCaptureFilter_, PINDIR_OUTPUT, PIN_CATEGORY_CAPTURE ) );
if( !pPin )
return E_FAIL;
CComQIPtr<IAMStreamConfig> pConfig( pPin );
if( !pConfig )
return E_FAIL;
AM_MEDIA_TYPE mt = { 0 };
VIDEOINFOHEADER vih = { 0 };
if( videoStandard_ == AnalogVideo_NTSC_M )
vih.AvgTimePerFrame = 333667;
else
vih.AvgTimePerFrame = 400000;
vih.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
vih.bmiHeader.biWidth = captureResolution_.cx;
vih.bmiHeader.biHeight = captureResolution_.cy;
vih.bmiHeader.biPlanes = 1;
vih.bmiHeader.biBitCount = 16;
vih.bmiHeader.biCompression = mmioFOURCC('Y','U','Y','2');
vih.bmiHeader.biSizeImage = vih.bmiHeader.biWidth * vih.bmiHeader.biHeight * 2;
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_YUY2;
mt.bFixedSizeSamples = TRUE;
mt.bTemporalCompression = FALSE;
mt.lSampleSize = vih.bmiHeader.biSizeImage;
mt.formattype = FORMAT_VideoInfo;
mt.cbFormat = sizeof( VIDEOINFOHEADER );
mt.pbFormat = (BYTE*)&vih;
mt.pUnk = NULL;
return pConfig->SetFormat( &mt ); // SUCCESS - always
}
我也配置了样本采集器,虽然我知道它只考虑主要类型和子类型。它并不关心其余部分。
HRESULT GraphBuilder::configureVideoSampleGrabber( ISampleGrabber * const pSampleGrabber )
{
AM_MEDIA_TYPE mt = { 0 };
VIDEOINFOHEADER vih = { 0 };
if( videoStandard_ == AnalogVideo_NTSC_M )
vih.AvgTimePerFrame = 333667;
else
vih.AvgTimePerFrame = 400000;
vih.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
vih.bmiHeader.biWidth = captureResolution_.cx;
vih.bmiHeader.biHeight = captureResolution_.cy;
vih.bmiHeader.biPlanes = 1;
vih.bmiHeader.biBitCount = 16;
vih.bmiHeader.biCompression = mmioFOURCC('Y','U','Y','2');
vih.bmiHeader.biSizeImage = vih.bmiHeader.biWidth * vih.bmiHeader.biHeight * 2;
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_YUY2;
mt.bFixedSizeSamples = TRUE;
mt.bTemporalCompression = FALSE;
mt.lSampleSize = vih.bmiHeader.biSizeImage;
mt.formattype = FORMAT_VideoInfo;
mt.cbFormat = sizeof( VIDEOINFOHEADER );
mt.pbFormat = (BYTE*)&vih;
mt.pUnk = NULL;
return pSampleGrabber->SetMediaType( &mt ); // SUCCESS - always
}
一旦过滤器在图中,但在连接之前调用此代码。所有返回值均为0。
在此示例中,captureResolution_.cx = 352和captureResolution_.cy = 240。
现在,问题是:为什么我总是通过SampleGrabber而不是352x240获得默认的720x480?我将捕获引脚配置为提供352x240。
答案 0 :(得分:1)
你在做什么是正确的,但是你想要改变一些事情。
您肯定想要查看Sample Grabber初始化。您不需要在其上设置完全指定的媒体类型。相反,你想要一个只有主要类型的部分媒体类型,一个子类型被初始化(其余的是NULL
'ed)。理由如下。
Sample Grabber只是一个插件,您可以将其配置为坚持特定的媒体类型。特别是,它无法以任何其他方式在上游连接上计算出连接类型,而不是直接将尝试与其内部引用类型进行比较,并根据此比较的结果接受或拒绝。话虽如此,您的Sample Grabber无法帮助设置分辨率,但如果某些不重要的字段中的介质类型不同,它可以拒绝连接。在Sample Grabber上需要视频YUY2就足够了,其余的格式是视频源的责任。
要确保此媒体类型适用于视频源,您始终可以在不使用Sample Grabber的情况下以交互方式连接它,并查看有效连接媒体类型的所有字段。