DirectShow使用过滤器支持NV12数据格式
2021-08-30
423
1
DirectShow默认是不支持NV12,H264等非原生态数据格式的,为了支持这些非原生态的格式,微软的DirectShow使用过滤器来实现。具体原理就是在对收到的不支持的数据格式进行转码,这样就可以渲染了。
说明:本段代码来自USB中文网技术交流群,感谢临江仙的分享!
class CFormatConvertFilter : public CTransformFilter
{
private:
CFormatConvertFilter(TCHAR *tszName, LPUNKNOWN punk, HRESULT *phr);
public:
static CUnknown * WINAPI CreateInstance(LPUNKNOWN punk, HRESULT *phr);
HRESULT CheckInputType(const CMediaType *mtIn);
HRESULT GetMediaType(int iPosition, CMediaType *pMediaType);
HRESULT CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut);
HRESULT DecideBufferSize(IMemAllocator * pAllocator, ALLOCATOR_PROPERTIES *pprop);
HRESULT Transform(IMediaSample *pIn, IMediaSample *pOut);
void SetConvertFmt(int fmt);
BOOL IsConvertHEVC();
BOOL IsConvertNV12();
protected:
int m_nConvertFmt;
};
HRESULT ConnectGraphFilters(BOOL Capture)
{
HRESULT hr = NOERROR;
CFormatConvertFilter *cf = NULL;
AM_MEDIA_TYPE *pmt;
gcap.pVSC->GetFormat(&pmt);
if (pmt->subtype == MEDIASUBTYPE_NV12)
{
cf = (CFormatConvertFilter *)CFormatConvertFilter::CreateInstance(NULL, &hr);
cf->SetConvertFmt(FormatConvert_NV12);
gcap.pFg->AddFilter(cf, L"NV12 Convert");
}
else if (gcap.capH265 || pmt->subtype == subtype_h265)
{
cf = (CFormatConvertFilter *)CFormatConvertFilter::CreateInstance(NULL, &hr);
cf->SetConvertFmt(FormatConvert_HEVC);
gcap.pFg->AddFilter(cf, L"HEVC Convert");
}
DeleteMediaType(pmt);
IBaseFilter *pSmartTee = NULL;
CoCreateInstance(CLSID_SmartTee, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pSmartTee);
gcap.pFg->AddFilter(pSmartTee, L"SmartTee");
IBaseFilter *pRender = NULL;
//CoCreateInstance(CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pRender);
//CoCreateInstance(CLSID_VideoMixingRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter,(void **)&pRender );
CoCreateInstance(CLSID_VideoMixingRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pRender);
gcap.pFg->AddFilter(pRender, L"Video Render");
IPin *pinCapOutput = gcap.capPin;
IPin *pinSTInput = NULL;
IPin *pinSTPreviewOut = NULL;
IPin *pinFormatInput = NULL;
IPin *pinFormatOutput = NULL;
IPin *pinRenderInput = NULL;
IPin *pinGrabIn = NULL;
IPin *pinGrabOut = NULL;
gcap.pBuilder->FindPin(pSmartTee, PINDIR_INPUT, NULL,
NULL, FALSE, 0, &pinSTInput);;
pSmartTee->FindPin(L"Preview", &pinSTPreviewOut);
gcap.pBuilder->FindPin(pRender, PINDIR_INPUT, NULL,
NULL, FALSE, 0, &pinRenderInput);
if (!Capture)
{
CSimpleFilter *pGrab = (CSimpleFilter *)CSimpleFilter::CreateInstance(NULL, &hr);
pGrab->SetCallBack(GrabCallBack);
gcap.pFg->AddFilter(pGrab, L"Grab");
gcap.pBuilder->FindPin((IBaseFilter *)pGrab, PINDIR_INPUT, NULL,
NULL, FALSE, 0, &pinGrabIn);
gcap.pBuilder->FindPin((IBaseFilter *)pGrab, PINDIR_OUTPUT, NULL,
NULL, FALSE, 0, &pinGrabOut);
gcap.pFg->Connect(pinCapOutput, pinGrabIn);
gcap.pFg->Connect(pinGrabOut, pinSTInput);
}
else
{
gcap.pFg->Connect(pinCapOutput, pinSTInput);
}
// hr = gcap.pFg->Connect(pinSTPreviewOut, pinGrabIn);
if (cf)
{
gcap.pBuilder->FindPin((IBaseFilter *)cf, PINDIR_INPUT, NULL,
NULL, FALSE, 0, &pinFormatInput);
gcap.pBuilder->FindPin((IBaseFilter *)cf, PINDIR_OUTPUT, NULL,
NULL, FALSE, 0, &pinFormatOutput);
gcap.pFg->Connect(pinSTPreviewOut, pinFormatInput);
hr = gcap.pFg->Connect(pinFormatOutput, pinRenderInput);
}
else
{
hr = gcap.pFg->Connect(pinSTPreviewOut, pinRenderInput);
}
if (Capture)
{
IPin *pinSTCapOut = NULL;
IPin *pinMuxIn = NULL;
pSmartTee->FindPin(L"Capture", &pinSTCapOut);
gcap.pBuilder->FindPin(gcap.pRender, PINDIR_INPUT, NULL,
NULL, FALSE, 0, &pinMuxIn);;
hr = gcap.pFg->Connect(pinSTCapOut, pinMuxIn);
SAFE_RELEASE(pinSTCapOut);
SAFE_RELEASE(pinMuxIn);
}
//SAFE_RELEASE(pGrab);
SAFE_RELEASE(pinGrabIn);
SAFE_RELEASE(pinGrabOut);
SAFE_RELEASE(pSmartTee);
SAFE_RELEASE(pRender);
SAFE_RELEASE(pinSTInput);
SAFE_RELEASE(pinSTPreviewOut);
SAFE_RELEASE(pinFormatInput);
SAFE_RELEASE(pinFormatOutput);
SAFE_RELEASE(pinRenderInput);
gcap.fPreviewFaked = TRUE;
return S_OK;
}
参考阅读:
常用图像像素格式 NV12、NV2、I420、YV12、YUYV http://www.usbzh.com/article/detail-214.html
HID人机交互QQ群:564808376
UAC音频QQ群:218581009
UVC相机QQ群:331552032
BOT&UASP大容量存储QQ群:258159197
STC-USB单片机QQ群:315457461
USB技术交流QQ群2:580684376
USB技术交流QQ群:952873936