Skip to content

Instantly share code, notes, and snippets.

@wrongbranch
Last active January 18, 2021 04:20
Show Gist options
  • Save wrongbranch/88ea47bffe7b5ebb4206ae0572114080 to your computer and use it in GitHub Desktop.
Save wrongbranch/88ea47bffe7b5ebb4206ae0572114080 to your computer and use it in GitHub Desktop.
DirectShow_Graph_trap_OpenCV.cpp
/*
DirectShow_Graph_trap_OpenCV.cpp
Camera -> Render and Grab (DirectShow) -> OpenCV
ref
OpenCV (old) DirectShow (old) 2008.12.15 Soaphacker
http://hisoap.jugem.jp/?eid=141
cv.lib cxcore.lib cvaux.lib highgui.lib strmiids.lib
DirectX DirectShow (old)
https://blog.zamuu.net/2011/0322/visualstudio2008-vc-directshow/
dxerr.lib dxgui.lib d3dx9.lib d3dx10.lib d3d9.lib
winmm.lib strmiids.lib strmbase.lib
rewrite for cv::Mat
test with OpenCV 3.4.12 https://github.com/opencv/opencv/releases/tag/3.4.12
x64/vc15/bin
opencv_world3412.dll
opencv_ffmpeg3412_64.dll
use Microsoft Visual Studio 2017
x64 compiler/linker
"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\Hostx64\x64\cl.exe"
-source-charset:utf-8 -execution-charset:utf-8
-EHsc -FeDirectShow_Graph_trap_OpenCV.exe DirectShow_Graph_trap_OpenCV.cpp
-I.
-IC:\OpenCV3\include
-link
/LIBPATH:C:\OpenCV3\x64\vc15\lib
/LIBPATH:"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\lib\x64"
/LIBPATH:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x64"
/LIBPATH:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\um\x64"
opencv_world3412.lib ole32.lib strmiids.lib
del .\DirectShow_Graph_trap_OpenCV.obj
DirectShow_Graph_trap_OpenCV
*/
#define UNICODE
#define _UNICODE
#include <wchar.h>
#define WIN32_LEAN_AND_MEAN
#define _WIN32_DCOM
#define _CRT_SECURE_NO_DEPRECATE
#include <windows.h>
#include <dshow.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// download qedit.h and edit it
#include <qedit.h> // CLSID_SampleGrabber ISampleGrabber IID_ISampleGrabber
// use CV_PI instead of M_PI
// #define _USE_MATH_DEFINES
#include <opencv2/opencv.hpp>
int main(int ac, char **av)
{
HRESULT hr = CoInitialize(NULL);
if(FAILED(hr)){
fprintf(stderr, "CoInitialize Failed\n");
return 1;
}
ICreateDevEnum *pDevEnum = NULL;
CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
IID_ICreateDevEnum, (void **)&pDevEnum);
IEnumMoniker *pClassEnum = NULL;
pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pClassEnum, 0);
if(!pClassEnum){
fprintf(stderr, "Device does not exist\n");
pDevEnum->Release();
CoUninitialize();
return 2;
}
// find Nth filter
IBaseFilter *pbf = NULL;
for(int c = 0; c < 3; ++c){
if(pbf){ pbf->Release(); pbf = NULL; }
ULONG cFetched;
IMoniker *pMoniker = NULL;
if(pClassEnum->Next(1, &pMoniker, &cFetched) == S_OK){
pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pbf);
pMoniker->Release();
}
}
pClassEnum->Release();
pDevEnum->Release();
if(!pbf){
fprintf(stderr, "Video Capture Filter not found\n");
CoUninitialize();
return 3;
}
IGraphBuilder *pGraph = NULL;
CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,
IID_IGraphBuilder, (void **)&pGraph);
pGraph->AddFilter(pbf, L"Video Capture");
IBaseFilter *pF = NULL;
CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (LPVOID *)&pF);
ISampleGrabber *pGrab = NULL;
pF->QueryInterface(IID_ISampleGrabber, (void **)&pGrab);
AM_MEDIA_TYPE amt;
ZeroMemory(&amt, sizeof(AM_MEDIA_TYPE));
amt.majortype = MEDIATYPE_Video;
amt.subtype = MEDIASUBTYPE_RGB24; // check
amt.formattype = FORMAT_VideoInfo;
pGrab->SetMediaType(&amt);
pGraph->AddFilter(pF, L"Grabber");
ICaptureGraphBuilder2 *pCapture = NULL;
CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC,
IID_ICaptureGraphBuilder2, (void **)&pCapture);
pCapture->SetFiltergraph(pGraph);
pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
pbf, NULL, pF);
IMediaControl *pMC = NULL;
pGraph->QueryInterface(IID_IMediaControl, (LPVOID *)&pMC);
pMC->Run(); // start render
pGrab->SetBufferSamples(TRUE); // Grab
pGrab->GetConnectedMediaType(&amt);
fprintf(stdout, "amt.lSampleSize = %dbytes\n", amt.lSampleSize);
VIDEOINFOHEADER *pVIH = (VIDEOINFOHEADER *)amt.pbFormat;
BITMAPINFO bmi;
ZeroMemory(&bmi, sizeof(bmi));
BITMAPINFOHEADER *pH = &bmi.bmiHeader;
CopyMemory(pH, &pVIH->bmiHeader, sizeof(BITMAPINFOHEADER));
fprintf(stdout, "%dx%d %dbits\n", pH->biWidth, pH->biHeight, pH->biBitCount);
// OpenCV from here
// only 24bit support
cv::namedWindow("Src", CV_WINDOW_AUTOSIZE | CV_WINDOW_FREERATIO);
cv::Mat frm(pH->biHeight, pH->biWidth, CV_8UC3);
while(1){
hr = pGrab->GetCurrentBuffer((long *)&pH->biSizeImage, (long *)frm.data);
if(FAILED(hr)){ if(cv::waitKey(50) == 'q') break; else continue; }
#if 0
// im->origin 0: left-top, 1: left-bottom
IplImage *im = cvCreateImage(cvSize(frm.cols, frm.rows), IPL_DEPTH_8U, 3);
if(!im->origin) cv::flip(frm, frm, 0); // reverse top <-> bottom
cvReleaseImage(&im);
#else
cv::flip(frm, frm, 0); // reverse top <-> bottom
#endif
cv::imshow("Src", frm);
int k = cv::waitKey(10);
if(k == 'q') break;
switch(k){
default: break; // skip
}
}
cv::destroyAllWindows();
// OpenCV end
pMC->Release(); // Filter Graph
pCapture->Release(); // Capture Graph
pGrab->Release();
pF->Release(); // Sample Grabber
pGraph->Release();
pbf->Release(); // Capture Filter
CoUninitialize();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment