ISampleGrabber可以将视频帧转换为特定的媒体类型吗?

can ISampleGrabber convert the video frames to a specific mediaType?

本文关键字:媒体 类型 视频 转换 ISampleGrabber      更新时间:2023-10-16

我在网上找到了这个很好的例子来解释directshow是如何工作的。

http://alax.info/trac/public/browser/trunk/Utilities/SetLifeCamStudioResolutionSample/SetLifeCamStudioResolutionSample.cpp

在这个例子中有两个采样器。一个叫NON-RGB grabber,一个叫RGB-grabber。

第一个:(NON-RGB)

#pragma region Non-RGB Sample Grabber
        {
            CComPtr<IBaseFilter> pBaseFilter;
            ATLENSURE_SUCCEEDED(pBaseFilter.CoCreateInstance(__uuidof(SampleGrabber)));
            ATLENSURE_SUCCEEDED(pFilterGraph->AddFilter(pBaseFilter, L"Non-RGB Sample Grabber")); // This will connect in MJPG format
            const CComQIPtr<ISampleGrabber> pSampleGrabber = pBaseFilter;
            ATLASSERT(pSampleGrabber);
#if TRUE
            // NOTE: IFilterGraph::Connect would do just fine, but with a real capture device, if we prefer having Smart Tee added, we need to use 
            //       Capture Graph Builder (only here)
            CComPtr<ICaptureGraphBuilder2> pCaptureGraphBuilder;
            ATLENSURE_SUCCEEDED(pCaptureGraphBuilder.CoCreateInstance(CLSID_CaptureGraphBuilder2));
            ATLENSURE_SUCCEEDED(pCaptureGraphBuilder->SetFiltergraph(pFilterGraph));
            ATLENSURE_SUCCEEDED(pCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, NULL, pCurrentOutputPin, NULL, pBaseFilter));
#else
            ATLENSURE_SUCCEEDED(pFilterGraph->Connect(pCurrentOutputPin, GetPin(pBaseFilter, 0)));
#endif
            MessageBox(GetActiveWindow(), _T("After Non-RGB Sample Grabber Connected"), _T("Debug"), MB_OK);
            pCurrentOutputPin = GetPin(pBaseFilter, 1);
        }
        #pragma endregion 

第二个:(RGB)

#pragma region RGB Sample Grabber
        {
            CComPtr<IBaseFilter> pBaseFilter;
            ATLENSURE_SUCCEEDED(pBaseFilter.CoCreateInstance(__uuidof(SampleGrabber)));
            ATLENSURE_SUCCEEDED(pFilterGraph->AddFilter(pBaseFilter, L"RGB Sample Grabber"));
            const CComQIPtr<ISampleGrabber> pSampleGrabber = pBaseFilter;
            ATLASSERT(pSampleGrabber);
            AM_MEDIA_TYPE MediaType;
            ZeroMemory(&MediaType, sizeof MediaType);
            MediaType.majortype = MEDIATYPE_Video;
            MediaType.subtype = MEDIASUBTYPE_RGB24;
            ATLENSURE_SUCCEEDED(pSampleGrabber->SetMediaType(&MediaType));
            ATLENSURE_SUCCEEDED(pFilterGraph->Connect(pCurrentOutputPin, GetPin(pBaseFilter, 0)));
            MessageBox(GetActiveWindow(), _T("After RGB Sample Grabber Connected"), _T("Debug"), MB_OK);
            pCurrentOutputPin = GetPin(pBaseFilter, 1);
        }
        #pragma endregion 

setmediatype()方法仅在"RGB"版本中使用。但我想知道。在MSDN页面上,setmediatype()表示样本采集器过滤器的输入引脚中可用的数据类型。如果可以在不设置媒体类型的情况下使用样本采集器,为什么我要将其设置为任何东西?

问题:

采样器做任何类型的媒体转换吗?

为什么要设置采样器的媒体类型?

如果相机的媒体类型设置为MJPG,并且我在采样器中将媒体类型设置为RGB24,会发生什么?

两者之间会有性能差异吗?为了提高软件的性能(fps),我应该删除一个采样器吗?

谢谢!

Sample Grabber Filter不做任何转换。这就是为什么它可以灵活地接受各种格式,包括视频和音频,而不需要注意特定的格式。

当您在Sample Grabber上设置媒体类型时,您强制它仅使用此类型。只接受这种类型,拒绝其他类型。与Intelligent Connect一起,如果可能的话,DirectShow可能会提供额外的过滤器来转换为请求的格式。24位RGB通常是可行的,因为它是一种"通用的未压缩视频格式"。这就是为什么将媒体类型设置为24位RGB是安全的,同时几乎任何压缩视频格式都会失败(除非源已经可以提供完全匹配的格式)。

请注意,如果智能连接提供额外的转换过滤器,它们附加到上游的样本采集器,而不是在它里面。