Skip to content

Instantly share code, notes, and snippets.

@bcachet
Last active March 2, 2016 13:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bcachet/9887801 to your computer and use it in GitHub Desktop.
Save bcachet/9887801 to your computer and use it in GitHub Desktop.
MFC application to connect to DirectShow's camera and display properties panel
#include "stdafx.h"
#include <atlstr.h>
#include <dshow.h>
//#include <afxwin.h>
#include <string>
using namespace std;
#define CHECK(err)\
if (FAILED((err))) { \
goto error; \
}
#define FREE_PTR_IF_NEEDED(pobj)\
if ((pobj) != NULL) {\
pobj->Release();\
pobj = NULL;\
}
HRESULT GetMonicker(IMoniker* & pMoniker, CString deviceName)
{
ICreateDevEnum *pSystemDeviceEnumerator= NULL;
IEnumMoniker *pVideoInputDeviceEnumerator= NULL;
HRESULT status = S_OK;
FREE_PTR_IF_NEEDED(pMoniker);
CHECK(CoCreateInstance( CLSID_SystemDeviceEnum,
NULL,
CLSCTX_INPROC,
IID_ICreateDevEnum,
(void**)&pSystemDeviceEnumerator));
CHECK(pSystemDeviceEnumerator->CreateClassEnumerator( CLSID_VideoInputDeviceCategory,
&pVideoInputDeviceEnumerator,
0));
while( pVideoInputDeviceEnumerator->Next( 1, &pMoniker, NULL) == S_OK ) {
VARIANT var;
VariantInit(&var);
IPropertyBag *pPropBag= NULL;
if (SUCCEEDED(pMoniker->BindToStorage( 0, 0, IID_IPropertyBag, (void**)&pPropBag))) {
pPropBag->AddRef();
if (SUCCEEDED(pPropBag->Read( L"FriendlyName", &var, 0))) {
CString sTemp(var.bstrVal);
if (sTemp.Find(deviceName) != string::npos) {
FREE_PTR_IF_NEEDED(pPropBag);
break;
}
}
}
FREE_PTR_IF_NEEDED(pPropBag);
VariantClear(&var);
}
goto clean;
error:
status = -1;
FREE_PTR_IF_NEEDED(pMoniker);
clean:
FREE_PTR_IF_NEEDED(pSystemDeviceEnumerator);
FREE_PTR_IF_NEEDED(pVideoInputDeviceEnumerator);
return status;
}
HRESULT CreateGraph(IBaseFilter* & pSource, IMoniker* pMoniker)
{
ICaptureGraphBuilder2 *pCaptureGraph = NULL;
IGraphBuilder* pFilterGraph = NULL;
HRESULT status = S_OK;
CHECK(pMoniker->BindToObject( 0, 0, IID_IBaseFilter, (void**)&pSource));
CHECK(CoCreateInstance( CLSID_CaptureGraphBuilder2,
NULL,
CLSCTX_INPROC,
IID_ICaptureGraphBuilder2,
(void**)&pCaptureGraph));
CHECK(CoCreateInstance( CLSID_FilterGraph,
NULL,
CLSCTX_INPROC,
IID_IGraphBuilder,
(void **)&pFilterGraph));
CHECK(pCaptureGraph->SetFiltergraph(pFilterGraph));
CHECK(pFilterGraph->AddFilter(pSource, L"Video Capture"));
CHECK(pCaptureGraph->RenderStream( &PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video,
pSource,
NULL,
NULL));
goto clean;
error:
if (pFilterGraph != NULL) {
pFilterGraph->RemoveFilter(pSource);
}
FREE_PTR_IF_NEEDED(pSource);
status = -1;
clean:
FREE_PTR_IF_NEEDED(pFilterGraph);
FREE_PTR_IF_NEEDED(pCaptureGraph);
return status;
}
HRESULT GetPin( IPin* &pPin,
IBaseFilter* pFilter,
PIN_DIRECTION pinDirection,
const GUID* pMajorMediaType = NULL,
const GUID* pPinCategory= NULL)
{
ICaptureGraphBuilder2 *pCaptureGraph = NULL;
HRESULT status = S_OK;
CHECK(CoCreateInstance( CLSID_CaptureGraphBuilder2,
NULL,
CLSCTX_INPROC,
IID_ICaptureGraphBuilder2,
(void**)&pCaptureGraph));
CHECK(pCaptureGraph->FindPin(pFilter, pinDirection, pPinCategory, pMajorMediaType, false, 0, &pPin));
goto clean;
error:
status = -1;
clean:
FREE_PTR_IF_NEEDED(pCaptureGraph);
return status;
}
HRESULT GetCaptureVideoPin(IPin* &pPin, IBaseFilter* pFilter)
{
return GetPin(pPin, pFilter, PINDIR_OUTPUT, &MEDIATYPE_Video, &PIN_CATEGORY_CAPTURE);
}
HRESULT DisplayPropertyPages(IUnknown* Source)
{
HRESULT status = S_OK;
ISpecifyPropertyPages* pSpecifyPropertyPages= NULL;
CAUUID cauuid= { 0, NULL};
CHECK(Source->QueryInterface( IID_ISpecifyPropertyPages, (void**)&pSpecifyPropertyPages));
CHECK(pSpecifyPropertyPages->GetPages( &cauuid));
CHECK(OleCreatePropertyFrame( NULL,
0,
0,
OLESTR("uEye Capture Device Pin"),
1,
(IUnknown**)&Source,
cauuid.cElems,
(GUID*)cauuid.pElems,
0,
0,
NULL));
goto clean;
error:
status = -1;
clean:
FREE_PTR_IF_NEEDED(pSpecifyPropertyPages);
CoTaskMemFree( cauuid.pElems);
cauuid.pElems= NULL;
cauuid.cElems= 0;
return status;
}
int _tmain(int argc, _TCHAR* argv[])
{
IMoniker *pMoniker= NULL;
IBaseFilter *pSource = NULL;
IPin *pPin = NULL;
HRESULT status = S_OK;
CHECK(CoInitialize(NULL));
CHECK(GetMonicker(pMoniker, L"UI231"));
CHECK(CreateGraph(pSource, pMoniker));
CHECK(DisplayPropertyPages(pSource));
CHECK(GetCaptureVideoPin(pPin, pSource));
CHECK(DisplayPropertyPages(pPin));
goto clean;
error:
status = -1;
clean:
FREE_PTR_IF_NEEDED(pMoniker);
FREE_PTR_IF_NEEDED(pSource);
CoUninitialize();
return status;
}
To compile the C++ project, you will need to create a MFC console application and to link to Strmiids.lib (Project Options > Linker > Input > Additional Dependencies)
unit DS;
interface
uses
SysUtils,
DirectShow9,
ActiveX;
type
EFailedStatus = class(Exception);
procedure CHECK(err : HRESULT; err_msg : string = '');
function GetMonicker(var AMoniker : IMoniker) : HRESULT;
function CreateGraph(var ASource : IBaseFilter; AMoniker : IMoniker) : HRESULT;
function GetPin(var APin : IPin; ASource : IBaseFilter; ADesiredPinDirection : PIN_DIRECTION; const ApMajorMediaType : pGuiD = nil; const ApPinCategory : pGUID = nil) : HRESULT; overload;
function DisplayPropertyPages(AFilter : IUnknown) : HRESULT;
implementation
procedure CHECK(err : HRESULT; err_msg : string);
begin
if (FAILED(err)) then begin
raise EFailedStatus.Create(err_msg);
end;
end;
function GetMonicker(var AMoniker : IMoniker) : HRESULT;
var
pSystemDeviceEnumerator : ICreateDevEnum;
pVideoInputDeviceEnumerator : IEnumMoniker;
pPropertyBag : IPropertyBag;
v : OLEVariant;
begin
Result := S_OK;
pSystemDeviceEnumerator := nil;
pVideoInputDeviceEnumerator := nil;
try
try
CHECK(CoCreateInstance(CLSID_SystemDeviceEnum, nil, CLSCTX_INPROC, ICreateDevEnum, pSystemDeviceEnumerator), 'Creating System Device Enumerator');
CHECK(pSystemDeviceEnumerator.CreateClassEnumerator(CLSID_VideoInputDeviceCategory, pVideoInputDeviceEnumerator,0), 'Creating Video Input Device Enumerator');
while(pVideoInputDeviceEnumerator.Next(1, AMoniker, nil) = S_OK) do begin
VariantInit(v);
if (SUCCEEDED(AMoniker.BindToStorage(nil, nil, IPropertyBag, pPropertyBag)))then begin
if (SUCCEEDED(pPropertyBag.Read('FriendlyName', v, nil))) then begin
Break;
end;
end;
VariantClear(v);
end;
except
on EFailedStatus do begin
Result := S_FALSE;
end;
end;
finally
VariantClear(v);
pSystemDeviceEnumerator := nil;
pVideoInputDeviceEnumerator := nil;
pPropertyBag := nil;
end;
end;
function CreateGraph(var ASource : IBaseFilter; AMoniker : IMoniker) : HRESULT;
var
pCut, pTyp : pGuiD;
ACaptureGraph : ICaptureGraphBuilder2;
AFilterGraph : IGraphBuilder;
begin
try
try
Result := S_OK;
CHECK(AMoniker.BindToObject(nil, nil, IBaseFilter, ASource));
CHECK(CoCreateInstance(CLSID_CaptureGraphBuilder2, nil, CLSCTX_INPROC, ICaptureGraphBuilder2, ACaptureGraph));
CHECK(CoCreateInstance(CLSID_FilterGraph, nil, CLSCTX_INPROC, IGraphBuilder, AFilterGraph));
CHECK(ACaptureGraph.SetFiltergraph(AFilterGraph));
CHECK(AFilterGraph.AddFilter(ASource, 'Video Capture'));
New(pCut); pCut^ := PIN_CATEGORY_CAPTURE;
New(pTyp); pTyp^ := MEDIATYPE_Video;
CHECK(ACaptureGraph.RenderStream(pCut, pTyp, ASource, nil, nil));
except
on EFailedStatus do begin
Result := S_FALSE;
end;
end;
finally
ACaptureGraph := nil;
AFilterGraph := nil;
end;
end;
function GetPin(var APin : IPin; ASource : IBaseFilter; ADesiredPinDirection : PIN_DIRECTION; const ApMajorMediaType : pGuiD = nil; const ApPinCategory : pGUID = nil) : HRESULT; overload;
var
ACaptureGraph : ICaptureGraphBuilder2;
begin
Result := S_OK;
try
try
CHECK(CoCreateInstance(CLSID_CaptureGraphBuilder2, nil, CLSCTX_INPROC, ICaptureGraphBuilder2, ACaptureGraph));
CHECK(ACaptureGraph.FindPin(ASource, ADesiredPinDirection, ApPinCategory,
ApMajorMediaType, False, 0, APin));
except
on EFailedStatus do begin
Result := S_FALSE;
end;
end;
finally
ACaptureGraph := nil;
end;
end;
function DisplayPropertyPages(AFilter : IUnknown) : HRESULT;
var
SpecifyPropertyPages : ISpecifyPropertyPages;
CAUUID : TCAGUID;
begin
Result := S_OK;
SpecifyPropertyPages := nil;
try
try
CHECK(AFilter.QueryInterface(ISpecifyPropertyPages, SpecifyPropertyPages));
CHECK(SpecifyPropertyPages.GetPages(CAUUID));
CHECK(OleCreatePropertyFrame(0, 0, 0, 'Properties', 1, @AFilter, cauuid.cElems, CAUUID.pElems, 0, 0, nil));
except
on EFailedStatus do begin
Result := S_FALSE;
end;
end;
finally
CoTaskMemFree(CAUUID.pElems);
SpecifyPropertyPages := nil;
end;
end;
end.
program TestDS;
{$APPTYPE CONSOLE}
uses
SysUtils,
DirectShow9, ActiveX,
DS in 'DS.pas';
var
Moniker : IMoniker;
Source : IBaseFilter;
Pin : IPin;
pCut, pTyp : pGuiD;
begin
try
CoInitialize(nil);
try
CHECK(GetMonicker(Moniker));
CHECK(CreateGraph(Source, Moniker));
// CHECK(DisplayPropertyPages(Source));
New(pCut); pCut^ := PIN_CATEGORY_CAPTURE;
New(pTyp); pTyp^ := MEDIATYPE_Video;
CHECK(GetPin(Pin, Source, PINDIR_OUTPUT, pTyp, pCut));
CHECK(DisplayPropertyPages(Pin));
finally
CoUninitialize();
end;
except
on E: EFailedStatus do begin
Writeln(E.ClassName, ': ', E.Message);
end;
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
@KahnSoft
Copy link

KahnSoft commented Mar 2, 2016

IID_ISpecifyPropertyPages OMG an unresolved Desaster beetwen VMR Windowless and IMediaControl

No Human can Control grab Memory Frames with Property and 30 Hz..

only VMR9 Windowless with 3Hz is possible with property page

THE BEST CHOISE IS USE VFW AND ALL IS FINDE DAMED DXSHOW

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment