0
votes

I'm building a DirectShow graph. I have video capture filter that connects its output pin to the input pin of SampleGrabber. Before I connect two pins, I configure output pin like this:

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
}

I also configure the sample grabber, although I know it will consider only the major type and subtype. It doesn't care about the rest.

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
}

This code is called once the filters are in the graph, but BEFORE they are connected. All return values are 0. In this example, the captureResolution_.cx = 352 and captureResolution_.cy = 240.

Now, the question is: WHY do I get the default 720x480 always through the SampleGrabber instead of 352x240?? I configured the capture pin to deliver 352x240.

1

1 Answers

1
votes

What you are doing is about right, there are however a few things you want to change.

You definitely want to review your Sample Grabber initialization. You don't need a fully specified media type set on it. Instead you want a partial media type with only major type an subtype initialized (and the rest is NULL'ed). The rationale is the following.

Sample Grabber is just an inset which you configure to insist on specific media type. In particular, it is unable to work out a connection type on the upstream connection in any other way than straightforwardly compare attempts to its internal reference type and accept or reject depending on result of this comparison. Having said this, your Sample Grabber cannot help setting the resolution, but it can reject the connection if media type is different in some unimportant field. It is sufficient to require video, YUY2 on Sample Grabber, and the rest of the format is the responsibility of video source.

To make sure this media type is okay for the video source you can always connect it interactively without Sample Grabber and review all fields of effective connection media type.