简体   繁体   English

在输出引脚上忽略设置媒体类型

[英]Setting media type ignored on output pin

I'm building a DirectShow graph. 我正在建立DirectShow图。 I have video capture filter that connects its output pin to the input pin of SampleGrabber. 我有一个视频捕获滤波器,将其输出引脚连接到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. 所有返回值均为0。在此示例中,captureResolution_.cx = 352,captureResolution_.cy = 240。

Now, the question is: WHY do I get the default 720x480 always through the SampleGrabber instead of 352x240?? 现在,问题是: 为什么我总是通过SampleGrabber而不是352x240来获得默认的720x480? I configured the capture pin to deliver 352x240. 我将捕获引脚配置为提供352x240。

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. 您肯定要查看Sample Grabber初始化。 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). 相反,你想唯一的主要类型的部分媒体类型的子类型初始化(其余为NULL “版)。 The rationale is the following. 基本原理如下。

Sample Grabber is just an inset which you configure to insist on specific media type. Sample Grabber只是一个插图,您可以将其配置为坚持特定的媒体类型。 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. 话虽如此,您的Sample Grabber无法帮助设置分辨率,但是如果某些不重要字段中的媒体类型不同,它可能会拒绝连接。 It is sufficient to require video, YUY2 on Sample Grabber, and the rest of the format is the responsibility of video source. 在Sample Grabber上要求视频(YUY2)就足够了,其余格式由视频源负责。

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. 为确保该视频源可以使用此媒体类型,您始终可以不使用Sample Grabber进行交互式连接,并查看有效连接媒体类型的所有字段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM