Настройка типа носителя игнорируется на выходном контакте

0

Я строю график 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.

Теги:
video
winapi
directshow

1 ответ

1

То, что вы делаете, верно, однако есть несколько вещей, которые вы хотите изменить.

Вы определенно хотите просмотреть инициализацию образца Grabber. Вам не нужен полностью определенный тип носителя, установленный на нем. Вместо этого вы хотите, чтобы частичный тип мультимедиа с единственным типом был инициализирован подтипом (а остальное - NULL). Обоснование заключается в следующем.

Sample Grabber - это просто вставка, которую вы настраиваете, чтобы настаивать на определенном типе мультимедиа. В частности, он не может выработать тип соединения в восходящем соединении любым другим способом, чем просто сравнивать попытки его внутреннего ссылочного типа и принимать или отклонять в зависимости от результата этого сравнения. Сказав это, ваш образец Grabber не может помочь установить разрешение, но он может отклонить соединение, если тип носителя отличается в каком-то неважном поле. Достаточно требовать видео, YUY2 на Sample Grabber, а остальная часть формата - это источник видео.

Чтобы убедиться, что этот тип носителя подходит для источника видео, вы всегда можете подключить его интерактивно без Sample Grabber и просмотреть все поля эффективного типа медиа-соединения.

  • 0
    Я все это знаю. Вот почему я написал «он (smplGrabber) будет рассматривать только основной тип и подтип». Это ожидаемо, но не должен ли выходной контакт попытаться использовать ранее установленный формат во время следующей попытки подключения? Я полагаю, что это должно и образец граббер должен просто проверить основной тип и подтип (цветовой формат). Поскольку это совпадение, разрешение должно быть 352х240. Или я что-то упустил? Я имею в виду, что я могу написать свою собственную версию сэмплера, но это бессмысленно, потому что я хочу, чтобы этот фильтр принимал любое разрешение в желаемом цветовом формате. И образец граббер делает именно это.
  • 0
    После того, как они не смогли подключиться напрямую, возможны и ожидаются последующие попытки, по усмотрению исходного фильтра, а затем в зависимости от фильтров, участвующих в Intelligent Connect. Может быть другой фильтр, переключающийся (вкл. Неправильно) на 352x240, и / или фильтр источника принимает ваш формат и затем пытается подключиться, используя чересстрочный видеоформат (который отклоняется SG) или блок VIH2. Я не думаю, что есть ответ на ваш вопрос в предоставленной информации. Ясно, что они не могут договориться о первичном типе соединения, чтобы понять, почему именно вам нужно знать, какие типы носителей используются.
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню