Я строю график 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.
Теперь вопрос: ПОЧЕМУ я получаю по умолчанию 720x480 всегда через SampleGrabber вместо 352x240?? Я сконфигурировал вывод для вывода 352x240.
То, что вы делаете, верно, однако есть несколько вещей, которые вы хотите изменить.
Вы определенно хотите просмотреть инициализацию образца Grabber. Вам не нужен полностью определенный тип носителя, установленный на нем. Вместо этого вы хотите, чтобы частичный тип мультимедиа с единственным типом был инициализирован подтипом (а остальное - NULL
). Обоснование заключается в следующем.
Sample Grabber - это просто вставка, которую вы настраиваете, чтобы настаивать на определенном типе мультимедиа. В частности, он не может выработать тип соединения в восходящем соединении любым другим способом, чем просто сравнивать попытки его внутреннего ссылочного типа и принимать или отклонять в зависимости от результата этого сравнения. Сказав это, ваш образец Grabber не может помочь установить разрешение, но он может отклонить соединение, если тип носителя отличается в каком-то неважном поле. Достаточно требовать видео, YUY2 на Sample Grabber, а остальная часть формата - это источник видео.
Чтобы убедиться, что этот тип носителя подходит для источника видео, вы всегда можете подключить его интерактивно без Sample Grabber и просмотреть все поля эффективного типа медиа-соединения.